From f1950fbb98e98904af0546299106d7d07281ba50 Mon Sep 17 00:00:00 2001 From: idan Date: Tue, 1 Sep 2026 16:07:22 +0800 Subject: [PATCH 1/8] docs: generate SimilarWeb pricing disclosures from contract --- .github/workflows/sync-openapi.yml | 6 + .../workflows/validate-similarweb-pricing.yml | 65 ++ README.md | 12 + docs.json | 6 +- evaluate/pricing.mdx | 1 + guides/pricing.mdx | 26 +- guides/pricing/per-call-api-pricing.mdx | 20 +- guides/pricing/similarweb.mdx | 256 ++++++++ llms.txt | 3 + openapi/similarweb.json | 46 +- scripts/check_similarweb_pricing.py | 140 +++++ scripts/generate_similarweb_pricing_docs.py | 595 ++++++++++++++++++ zh/evaluate/pricing.mdx | 1 + zh/guides/pricing.mdx | 24 +- zh/guides/pricing/per-call-api-pricing.mdx | 16 +- zh/guides/pricing/similarweb.mdx | 256 ++++++++ 16 files changed, 1413 insertions(+), 60 deletions(-) create mode 100644 .github/workflows/validate-similarweb-pricing.yml create mode 100644 guides/pricing/similarweb.mdx create mode 100644 scripts/check_similarweb_pricing.py create mode 100644 scripts/generate_similarweb_pricing_docs.py create mode 100644 zh/guides/pricing/similarweb.mdx diff --git a/.github/workflows/sync-openapi.yml b/.github/workflows/sync-openapi.yml index c6d4511a..da7fad19 100644 --- a/.github/workflows/sync-openapi.yml +++ b/.github/workflows/sync-openapi.yml @@ -66,6 +66,9 @@ jobs: - name: Install dependencies run: pip install pyyaml + - name: Verify generated SimilarWeb pricing surfaces + run: python scripts/generate_similarweb_pricing_docs.py --check + # ── 3. Generate consolidated spec ────────────────────────────── - name: Consolidate OpenAPI specs id: consolidate @@ -88,6 +91,9 @@ jobs: sys.exit(1) " + - name: Verify SimilarWeb pricing contract + run: python scripts/check_similarweb_pricing.py --generated /tmp/openapi.yaml + # ── 4. Commit spec back to this repo (public download URL) ───── - name: Copy spec to docs repo root run: cp /tmp/openapi.yaml openapi.yaml diff --git a/.github/workflows/validate-similarweb-pricing.yml b/.github/workflows/validate-similarweb-pricing.yml new file mode 100644 index 00000000..dffba9d9 --- /dev/null +++ b/.github/workflows/validate-similarweb-pricing.yml @@ -0,0 +1,65 @@ +name: Validate SimilarWeb Pricing Docs + +on: + pull_request: + paths: + - ".github/workflows/validate-similarweb-pricing.yml" + - ".github/workflows/sync-openapi.yml" + - "docs.json" + - "llms.txt" + - "openapi/**" + - "api-reference/similarweb/**" + - "zh/api-reference/similarweb/**" + - "guides/pricing.mdx" + - "guides/pricing/**" + - "zh/guides/pricing.mdx" + - "zh/guides/pricing/**" + - "evaluate/pricing.mdx" + - "zh/evaluate/pricing.mdx" + - "scripts/check_similarweb_pricing.py" + - "scripts/consolidate_openapi.py" + - "scripts/generate_similarweb_pricing_docs.py" + workflow_dispatch: + +permissions: + contents: read + +jobs: + validate: + name: Check generated pricing surfaces + runs-on: ubuntu-latest + timeout-minutes: 5 + + steps: + - name: Checkout docs repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Set up Node.js for Mintlify validation + uses: actions/setup-node@v4 + with: + node-version: "20.17" + + - name: Install dependencies + run: pip install pyyaml + + - name: Check checked-in pricing surfaces + run: python scripts/generate_similarweb_pricing_docs.py --check + + - name: Consolidate OpenAPI source + run: python scripts/consolidate_openapi.py --output /tmp/openapi.yaml + + - name: Check generated OpenAPI and discovery paths + run: python scripts/check_similarweb_pricing.py --generated /tmp/openapi.yaml + + - name: Validate generated docs and OpenAPI with Mintlify + run: npx --yes mint@4.2.854 validate + + - name: Check patch whitespace + run: git diff --check "origin/${{ github.base_ref }}...HEAD" diff --git a/README.md b/README.md index fa263fe5..3a2af99b 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,18 @@ python3 scripts/consolidate_openapi.py --output /tmp/aisa-openapi.yaml `openapi/*.json` files are the source of truth. The root `openapi.yaml` is generated by the sync workflow and should not be edited directly. +When changing SimilarWeb's `x-aisa-pricing` metadata, regenerate the human +pricing disclosures and guides before opening a pull request: + +```bash +python3 scripts/generate_similarweb_pricing_docs.py --write +python3 scripts/generate_similarweb_pricing_docs.py --check +``` + +The generator deliberately derives the endpoint copy and English/Chinese +guides from the OpenAPI metadata so no second hand-authored rate schedule can +drift from the agent-facing contract. + After the generated `openapi.yaml` commit is pushed to `main`, the workflow sends a `docs_openapi_updated` repository dispatch to `AIsa-team/aisa-tool-router`. Its payload contains the immutable docs commit, diff --git a/docs.json b/docs.json index 7da62032..bf7549a7 100644 --- a/docs.json +++ b/docs.json @@ -127,7 +127,8 @@ "pages": [ "guides/pricing", "guides/pricing/ai-model-pricing-llm-inference", - "guides/pricing/per-call-api-pricing" + "guides/pricing/per-call-api-pricing", + "guides/pricing/similarweb" ] }, { @@ -2145,7 +2146,8 @@ "pages": [ "zh/guides/pricing", "zh/guides/pricing/ai-model-pricing-llm-inference", - "zh/guides/pricing/per-call-api-pricing" + "zh/guides/pricing/per-call-api-pricing", + "zh/guides/pricing/similarweb" ] }, { diff --git a/evaluate/pricing.mdx b/evaluate/pricing.mdx index cea524d2..535d1523 100644 --- a/evaluate/pricing.mdx +++ b/evaluate/pricing.mdx @@ -11,6 +11,7 @@ Use current pricing sources for final decisions. - [AI Model Pricing](/guides/pricing/ai-model-pricing-llm-inference) for model-pricing guidance. - [Per-call API Pricing](/guides/pricing/per-call-api-pricing) for API billing guidance. +- [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb) for SimilarWeb's formula-based endpoint pricing. - [Wallet and Payments](/guides/pricing/wallet) for funding and balance behavior. - [Usage Logs](/guides/dashboard/usage-logs) for observed account usage. - The live model catalog or exact API page for current capability context. diff --git a/guides/pricing.mdx b/guides/pricing.mdx index 57910eaf..03728d37 100644 --- a/guides/pricing.mdx +++ b/guides/pricing.mdx @@ -2,15 +2,15 @@ title: AIsa Pricing – Usage-Based Billing for LLMs & Data APIs excerpt: >- AIsa pricing overview covering token-based billing for 100+ AI models and - flat per-call pricing for search, financial, Twitter, and data APIs. No - subscriptions — pay only for what you use. + fixed and variable data-API pricing. No subscriptions — pay only for what + you use. --- AIsa uses a usage-based billing system. Charges are applied based on the type of API you use. -There are two distinct pricing models: +There are two pricing categories: 1. **AI Model (LLM) Pricing:** billed per token -2. **Per-Call API Pricing:** billed per request +2. **Data API Pricing:** fixed per request for many APIs; some providers use a credit formula based on request dimensions or returned rows This page provides a high-level overview of both models and links to their detailed pricing pages. @@ -39,15 +39,15 @@ This pricing model applies to: For the full model pricing table and detailed billing explanation, see **AI Model Pricing** -## 2. Per-Call API Pricing +## 2. Data API Pricing -All non-LLM APIs use a fixed per-request billing model. +Many non-LLM APIs use a fixed per-request billing model. Some data providers have a variable credit-based model instead. ![Twitter API page on AIsa showing each endpoint with its fixed per-call price](/images/bdd00244-twitter-api-per-call.png) -Each API page lists its endpoints with the price attached to each one — in the Twitter example above, `/apis/v1/twitter/user/last_tweets` is billed at \$0.0036 per call while `/apis/v1/twitter/user/followers` is billed at \$0.036 per call. +For fixed-price APIs, each API page lists its endpoints with the price attached to each one — in the Twitter example above, `/apis/v1/twitter/user/last_tweets` is billed at \$0.0036 per call while `/apis/v1/twitter/user/followers` is billed at \$0.036 per call. -Each successful request to an endpoint incurs a predefined charge, regardless of response size. +For those APIs, each successful request to an endpoint incurs a predefined charge, regardless of response size. This pricing model applies to APIs such as: @@ -58,16 +58,20 @@ This pricing model applies to APIs such as: * Twitter APIs * Other structured data and retrieval services -For endpoint-level pricing details and billing behavior, see **Per-Call API Pricing** +For endpoint-level pricing details and billing behavior, see [Per-Call API Pricing](/guides/pricing/per-call-api-pricing). + +### SimilarWeb: formula-based pricing + +SimilarWeb is a paid data API with a credit formula. Depending on the endpoint, cost can be fixed, driven by request dimensions, or driven by returned rows. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb) before a paid request; it shows the current formula, cost driver, example, and endpoint-specific control. ## Choosing the Correct Pricing Model If your API request: * Uses a language model to generate text → **Token-based pricing applies** -* Retrieves structured data or performs a search → **Per-call pricing applies** +* Retrieves structured data or performs a search → **Read that API's pricing model**; it may be fixed per call or formula-based. -The Models catalog shows per-token prices, and each API page shows the per-call price of every endpoint. +The Models catalog shows per-token prices. Fixed-price API pages show per-call prices; formula-priced APIs publish their formula and cost controls with the endpoint documentation. ## Usage Tracking and Transparency diff --git a/guides/pricing/per-call-api-pricing.mdx b/guides/pricing/per-call-api-pricing.mdx index f037c12b..38089731 100644 --- a/guides/pricing/per-call-api-pricing.mdx +++ b/guides/pricing/per-call-api-pricing.mdx @@ -1,15 +1,19 @@ --- -title: Per-Call API Pricing – Search, Financial, Twitter & Data APIs +title: Per-Call API Pricing – Fixed-Price Search, Financial, Twitter & Data APIs excerpt: >- - Fixed per-request pricing for AIsa's non-LLM APIs including web search, - financial data, Twitter, YouTube, and scholar endpoints. Simple flat-rate - billing with no token counting. + Fixed per-request pricing for eligible AIsa data APIs including web search, + financial data, Twitter, YouTube, and scholar endpoints. Variable-cost data + APIs have their own documented cost model. --- -This page explains the pricing model for all non-LLM APIs available through AIsa. +This page explains the fixed-price model for eligible non-LLM APIs available through AIsa. + + + **IMPORTANT:** This page does not make every data API fixed-price. SimilarWeb endpoints may be fixed, priced per returned row, or priced from request dimensions. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb) before a paid SimilarWeb request. + ![Tavily Search API page on AIsa showing each endpoint with its flat per-call price](/images/6bd32ad1-tavily-search-per-call.png) -These APIs use a **fixed per-request billing model**. Each successful request to an endpoint incurs a predefined charge, independent of response size, token count, or processing time. In the Tavily Search example above, crawl, extract, map, and search each cost \$0.0096 per call regardless of how much data comes back. +These eligible APIs use a **fixed per-request billing model**. Each successful request to an endpoint incurs a predefined charge, independent of response size, token count, or processing time. In the Tavily Search example above, crawl, extract, map, and search each cost \$0.0096 per call regardless of how much data comes back. Per-call pricing applies to APIs such as: @@ -47,7 +51,7 @@ If a request fails before processing (for example, due to authentication errors) Each per-call API endpoint has its own defined cost. -On each API page, every endpoint listing displays: +On each fixed-price API page, every endpoint listing displays: * HTTP method and endpoint name * API path @@ -109,6 +113,6 @@ This allows you to: * All prices are listed in USD. * Billing is triggered per successful API request. * There is no token-based billing for these endpoints. -* Response size does not impact cost. +* Response size does not impact cost for the fixed-price APIs covered by this page. * Pricing may change as endpoints evolve. * Refer to the API pages for up-to-date pricing. diff --git a/guides/pricing/similarweb.mdx b/guides/pricing/similarweb.mdx new file mode 100644 index 00000000..1668785f --- /dev/null +++ b/guides/pricing/similarweb.mdx @@ -0,0 +1,256 @@ +--- +title: SimilarWeb Pricing & Cost Control +excerpt: >- + Machine-derived SimilarWeb credit formulas, examples, and cost controls + for people and agents before a paid request. +--- + +SimilarWeb is a paid data API with credit-based pricing. Its catalog display value is not always a fixed, request-specific quote. + + + **IMPORTANT:** Before a paid SimilarWeb request, read the matching endpoint disclosure below, state the cost driver and documented exposure, and use the smallest scope that answers the task. For request-dimension pricing, obtain a budget decision before execution. + + +This page is generated from each endpoint's `x-aisa-pricing` object in the [machine-readable OpenAPI](https://aisa.one/openapi.yaml). It intentionally does not maintain a second hand-authored rate schedule. + +## How settlement works + +SimilarWeb uses a two-phase credit model: the gateway can report a pre-authorization estimate in `X-AISA-Estimated-Credits`, then reports settled usage in `X-AISA-Accounted-Credits` and `X-AISA-Price-USD`. The provider-level API contract says that only successful, non-empty responses are billed. These formulas and examples describe the published schedule; they are not a server-authoritative quote endpoint. + +Do not treat a catalog `pricing.normal` value of `0` as a free SimilarWeb request. + +## Request-dimension pricing + + +### [Traffic & Engagement](/api-reference/similarweb/get_similarweb-website-traffic-engagement) + +- **Pricing mode:** request-dimension credit pricing. +- **Credit rate:** `1 credit / (metric x month)` at `$0.10` per credit. +- **Formula:** `credits = 1 x metrics x periods`. +- **Cost drivers:** `metrics`: number of metrics requested; `periods`: number of months in the date window. +- **Current schedule example:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods.` +- **Control:** Cost varies with `metrics`, the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. + + +### [Website Ranking](/api-reference/similarweb/get_similarweb-website-ranking) + +- **Pricing mode:** request-dimension credit pricing. +- **Credit rate:** `2 credits / (month)` at `$0.10` per credit. +- **Formula:** `credits = 2 x periods`. +- **Cost drivers:** `periods`: number of months in the date window. +- **Current schedule example:** `minimal (1 month) = 2 credits ($0.20); cost grows with periods.` +- **Control:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. + + +### [PPC Spend](/api-reference/similarweb/get_similarweb-website-ppc-spend) + +- **Pricing mode:** request-dimension credit pricing. +- **Credit rate:** `1 credit / (month)` at `$0.10` per credit. +- **Formula:** `credits = 1 x periods`. +- **Cost drivers:** `periods`: number of months in the date window. +- **Current schedule example:** `minimal (1 month) = 1 credit ($0.10); cost grows with periods.` +- **Control:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. + + +### [Marketing Channel Sources](/api-reference/similarweb/get_similarweb-website-marketing-channel-sources-legacy) + +- **Pricing mode:** request-dimension credit pricing. +- **Credit rate:** `7 credits / (month)` at `$0.10` per credit. +- **Formula:** `credits = 7 x periods`. +- **Cost drivers:** `periods`: number of months in the date window. +- **Current schedule example:** `minimal (1 month) = 7 credits ($0.70); cost grows with periods.` +- **Control:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. + + +### [Deduplicated Audience](/api-reference/similarweb/get_similarweb-website-deduplicated-audience) + +- **Pricing mode:** request-dimension credit pricing. +- **Credit rate:** `7 credits / (month)` at `$0.10` per credit. +- **Formula:** `credits = 7 x periods`. +- **Cost drivers:** `periods`: number of months in the date window. +- **Current schedule example:** `minimal (1 month) = 7 credits ($0.70); cost grows with periods.` +- **Control:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. + + +### [Website Traffic Snapshot](/api-reference/similarweb/get_similarweb-website-traffic-snapshot) + +- **Pricing mode:** request-dimension credit pricing. +- **Credit rate:** `1 credit / (metric x month)` at `$0.10` per credit. +- **Formula:** `credits = 1 x metrics x periods`. +- **Cost drivers:** `metrics`: number of metrics requested; `periods`: number of months in the date window. +- **Provider-controlled schedule example:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters. +- **Control:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. Treat the published example as the documented exposure and obtain a budget decision before execution. + + +### [Website Traffic Trend](/api-reference/similarweb/get_similarweb-website-traffic-trend) + +- **Pricing mode:** request-dimension credit pricing. +- **Credit rate:** `1 credit / (metric x month)` at `$0.10` per credit. +- **Formula:** `credits = 1 x metrics x periods`. +- **Cost drivers:** `metrics`: number of metrics requested; `periods`: number of months in the date window. +- **Provider-controlled schedule example:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters. +- **Control:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. Treat the published example as the documented exposure and obtain a budget decision before execution. + +## Returned-row pricing + + +### [Top Sites Ranking](/api-reference/similarweb/get_similarweb-website-top-sites-ranking) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `1 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(1 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 1 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [Referrals](/api-reference/similarweb/get_similarweb-website-referrals) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `4 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(4 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 4 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [Ad Networks](/api-reference/similarweb/get_similarweb-website-ad-networks) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `3 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(3 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [SimilarSites](/api-reference/similarweb/get_similarweb-website-similar-sites) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `5 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(5 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [Audience Interest](/api-reference/similarweb/get_similarweb-website-audience-interest) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `5 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(5 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [Audience Overlap](/api-reference/similarweb/get_similarweb-website-audience-overlap) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `2 / row (max 5 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(2 x rows); rows capped at 5`. +- **Cost drivers:** `limit`: charge scales with rows returned at 2 credit/row; at most 5 rows are billed. +- **Published maximum-exposure example:** `5 rows = 10 credits ($1.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`. +- **Control:** This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. + + +### [Popular Pages](/api-reference/similarweb/get_similarweb-website-popular-pages) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `3 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(3 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [Website Subdomains](/api-reference/similarweb/get_similarweb-website-subdomains) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `2 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(2 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 2 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [Keyword Competitors](/api-reference/similarweb/get_similarweb-search-keyword-competitors) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `0.03 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(0.03 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 0.03 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [Website Keywords](/api-reference/similarweb/get_similarweb-search-website-keywords) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `0.1 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(0.1 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [SERP Players - Clicks over time](/api-reference/similarweb/get_similarweb-search-serp-players-timeseries) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `0.02 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(0.02 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 0.02 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [SERP Players - Aggregated](/api-reference/similarweb/get_similarweb-search-serp-players-aggregated) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `0.07 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(0.07 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 0.07 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [Landing Pages](/api-reference/similarweb/get_similarweb-search-landing-pages) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `0.1 / row (max 20 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(0.1 x rows); rows capped at 20`. +- **Cost drivers:** `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. +- **Current schedule example:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` +- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. + + +### [Website Top Geographies](/api-reference/similarweb/get_similarweb-website-top-geographies) + +- **Pricing mode:** returned-row credit pricing. +- **Credit rate:** `3 / row (max 10 rows)` at `$0.10` per credit. +- **Formula:** `credits = ceil(3 x rows); rows capped at 10`. +- **Cost drivers:** `limit`: charge scales with rows returned at 3 credit/row; at most 10 rows are billed. +- **Published maximum-exposure example:** `10 rows = 30 credits ($3.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`. +- **Control:** This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. + +## Fixed per-request pricing + + +### [Demographics](/api-reference/similarweb/get_similarweb-website-demographics) + +- **Pricing mode:** fixed per request. +- **Credit rate:** `8 credits (fixed)` at `$0.10` per credit. +- **Formula:** `credits = 8 (fixed per request)`. +- **Cost drivers:** `(none)`: flat per-request credit charge. +- **Current schedule example:** `1 request = 8 credits ($0.80)` +- **Control:** The published credit charge is fixed for this request type. + + +### [Website Technologies](/api-reference/similarweb/get_similarweb-website-technologies) + +- **Pricing mode:** fixed per request. +- **Credit rate:** `10 credits (fixed)` at `$0.10` per credit. +- **Formula:** `credits = 10 (fixed per request)`. +- **Cost drivers:** `(none)`: flat per-request credit charge. +- **Current schedule example:** `1 request = 10 credits ($1.00)` +- **Control:** The published credit charge is fixed for this request type. diff --git a/llms.txt b/llms.txt index 0d5fb952..95565f03 100644 --- a/llms.txt +++ b/llms.txt @@ -10,6 +10,7 @@ Use this index to choose the smallest relevant documentation set. For product di - [Getting Started](https://aisa.one/docs/guides/getting-started-with-aisa): account, API key, and first-request setup. - [Authentication](https://aisa.one/docs/guides/authentication): Bearer tokens, key storage, and rotation. - [Pricing and Billing](https://aisa.one/docs/guides/pricing): model and per-call API billing entry point. +- [SimilarWeb Pricing & Cost Control](https://aisa.one/docs/guides/pricing/similarweb): machine-derived credit formulas, examples, and required scope controls for paid SimilarWeb endpoints. - [Errors](https://aisa.one/docs/api-reference/errors): error formats and handling. - [Rate Limits](https://aisa.one/docs/api-reference/rate-limits): limits and relevant headers. @@ -52,6 +53,7 @@ Use this index to choose the smallest relevant documentation set. For product di - [Twitter API](https://aisa.one/docs/api-reference/twitter/get_twitter-user-info): X/Twitter read and authenticated write routes. - [Scholar API](https://aisa.one/docs/api-reference/scholar/post_scholar-search-scholar): academic and mixed-source search. - [Prediction Market API](https://aisa.one/docs/api-reference/prediction-market/get_polymarket-events): Polymarket and Kalshi data. +- [SimilarWeb API](https://aisa.one/docs/api-reference/similarweb/get_similarweb-website-similar-sites): digital-intelligence data; load SimilarWeb pricing guidance before a paid call. ## Machine Discovery @@ -68,3 +70,4 @@ Use this index to choose the smallest relevant documentation set. For product di - Treat search results as discovery, fetched pages as evidence, and generated text as synthesis. - Separate read operations from writes and payments; verify authorization before side effects. - Check live availability, status, pricing, and authentication before relying on a capability. +- For SimilarWeb, load the matching endpoint and [SimilarWeb Pricing & Cost Control](https://aisa.one/docs/guides/pricing/similarweb); do not treat a catalog display value as a request-specific quote. diff --git a/openapi/similarweb.json b/openapi/similarweb.json index ddedff83..03e21dd3 100644 --- a/openapi/similarweb.json +++ b/openapi/similarweb.json @@ -38,7 +38,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Traffic & Engagement", - "description": "Traffic & Engagement. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.", + "description": "Traffic & Engagement. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Current schedule example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods.`\n\n**IMPORTANT:** Cost varies with `metrics`, the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#traffic-engagement) before a paid request.\n\n", "operationId": "get_similarweb_traffic_engagement", "parameters": [ { @@ -251,7 +251,7 @@ "example": "minimal (1 month) = 2 credits ($0.20); cost grows with periods." }, "summary": "Website Ranking", - "description": "Website Ranking. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.", + "description": "Website Ranking. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 credits / (month)` at `$0.10` per credit. Formula: `credits = 2 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 2 credits ($0.20); cost grows with periods.`\n\n**IMPORTANT:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#ranking) before a paid request.\n\n", "operationId": "get_similarweb_ranking", "parameters": [ { @@ -418,7 +418,7 @@ "example": "minimal (1 month) = 1 credit ($0.10); cost grows with periods." }, "summary": "PPC Spend", - "description": "PPC Spend. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.", + "description": "PPC Spend. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (month)` at `$0.10` per credit. Formula: `credits = 1 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 1 credit ($0.10); cost grows with periods.`\n\n**IMPORTANT:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#ppc-spend) before a paid request.\n\n", "operationId": "get_similarweb_ppc_spend", "parameters": [ { @@ -579,7 +579,7 @@ "example": "20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)" }, "summary": "Top Sites Ranking", - "description": "Top Sites Ranking. Response follows the SimilarWeb v5 envelope (meta + data).", + "description": "Top Sites Ranking. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#top-sites-ranking) before a paid request.\n\n", "operationId": "get_similarweb_top_sites_ranking", "parameters": [ { @@ -705,7 +705,7 @@ "example": "minimal (1 month) = 7 credits ($0.70); cost grows with periods." }, "summary": "Marketing Channel Sources", - "description": "Marketing Channel Sources. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.", + "description": "Marketing Channel Sources. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 7 credits ($0.70); cost grows with periods.`\n\n**IMPORTANT:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#marketing-channel-sources-legacy) before a paid request.\n\n", "operationId": "get_similarweb_marketing_channel_sources_legacy", "parameters": [ { @@ -880,7 +880,7 @@ "example": "20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)" }, "summary": "Referrals", - "description": "Referrals. Response follows the SimilarWeb v5 envelope (meta + data).", + "description": "Referrals. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `4 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(4 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 4 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#referrals) before a paid request.\n\n", "operationId": "get_similarweb_referrals", "parameters": [ { @@ -1077,7 +1077,7 @@ "example": "20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)" }, "summary": "Ad Networks", - "description": "Ad Networks. Response follows the SimilarWeb v5 envelope (meta + data).", + "description": "Ad Networks. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#ad-networks) before a paid request.\n\n", "operationId": "get_similarweb_ad_networks", "parameters": [ { @@ -1275,7 +1275,7 @@ "example": "20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)" }, "summary": "SimilarSites", - "description": "SimilarSites. Response follows the SimilarWeb v5 envelope (meta + data). Date window (upstream SimilarWeb constraint): start_date and end_date must span EXACTLY 3 consecutive months — a 1- or 2-month span is rejected with upstream error 120 ('must span exactly 3 month(s)'). That span must also be SimilarWeb's most recent supported window, which advances forward each month; an older or out-of-range span is rejected with error 101 ('Dates not in range'). In practice, request the three most recent completed months (e.g. if the latest published month is 2026-07, use start_date=2026-05 and end_date=2026-07). To read the exact currently-supported range, call SimilarWeb's /describe endpoint for this API.", + "description": "SimilarSites. Response follows the SimilarWeb v5 envelope (meta + data). Date window (upstream SimilarWeb constraint): start_date and end_date must span EXACTLY 3 consecutive months — a 1- or 2-month span is rejected with upstream error 120 ('must span exactly 3 month(s)'). That span must also be SimilarWeb's most recent supported window, which advances forward each month; an older or out-of-range span is rejected with error 101 ('Dates not in range'). In practice, request the three most recent completed months (e.g. if the latest published month is 2026-07, use start_date=2026-05 and end_date=2026-07). To read the exact currently-supported range, call SimilarWeb's /describe endpoint for this API.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#similar-sites) before a paid request.\n\n", "operationId": "get_similarweb_similar_sites", "parameters": [ { @@ -1478,7 +1478,7 @@ "example": "1 request = 8 credits ($0.80)" }, "summary": "Demographics", - "description": "Demographics. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must fall in the SAME month (exactly one monthly bucket).", + "description": "Demographics. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must fall in the SAME month (exactly one monthly bucket).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `8 credits (fixed)` at `$0.10` per credit. Formula: `credits = 8 (fixed per request)`. Cost drivers: `(none)`: flat per-request credit charge. Current schedule example: `1 request = 8 credits ($0.80)`\n\n**IMPORTANT:** The published credit charge is fixed for this request type. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#demographics) before a paid request.\n\n", "operationId": "get_similarweb_demographics", "parameters": [ { @@ -1673,7 +1673,7 @@ "example": "minimal (1 month) = 7 credits ($0.70); cost grows with periods." }, "summary": "Deduplicated Audience", - "description": "Deduplicated Audience. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.", + "description": "Deduplicated Audience. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 7 credits ($0.70); cost grows with periods.`\n\n**IMPORTANT:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#deduplicated-audience) before a paid request.\n\n", "operationId": "get_similarweb_deduplicated_audience", "parameters": [ { @@ -1860,7 +1860,7 @@ "example": "20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)" }, "summary": "Audience Interest", - "description": "Audience Interest. Response follows the SimilarWeb v5 envelope (meta + data).", + "description": "Audience Interest. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#audience-interest) before a paid request.\n\n", "operationId": "get_similarweb_audience_interest", "parameters": [ { @@ -2067,7 +2067,7 @@ "example": "5 rows = 10 credits ($1.00); limit=5 = 10 credits ($1.00)" }, "summary": "Audience Overlap", - "description": "Audience Overlap. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.", + "description": "Audience Overlap. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 / row (max 5 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 5`. Cost drivers: `limit`: charge scales with rows returned at 2 credit/row; at most 5 rows are billed. Published maximum-exposure example: `5 rows = 10 credits ($1.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`.\n\n**IMPORTANT:** This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#audience-overlap) before a paid request.\n\n", "operationId": "get_similarweb_audience_overlap", "parameters": [ { @@ -2205,7 +2205,7 @@ "example": "1 request = 10 credits ($1.00)" }, "summary": "Website Technologies", - "description": "Website Technologies. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must be the SAME month, and that month must be the latest available data month — a single monthly bucket that advances as SimilarWeb refreshes its data, and which may differ by country. Supplying any other month returns SimilarWeb error_code 101 (\"Dates not in range\"); the error message states the currently-allowed range.", + "description": "Website Technologies. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must be the SAME month, and that month must be the latest available data month — a single monthly bucket that advances as SimilarWeb refreshes its data, and which may differ by country. Supplying any other month returns SimilarWeb error_code 101 (\"Dates not in range\"); the error message states the currently-allowed range.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `10 credits (fixed)` at `$0.10` per credit. Formula: `credits = 10 (fixed per request)`. Cost drivers: `(none)`: flat per-request credit charge. Current schedule example: `1 request = 10 credits ($1.00)`\n\n**IMPORTANT:** The published credit charge is fixed for this request type. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#technologies) before a paid request.\n\n", "operationId": "get_similarweb_technologies", "parameters": [ { @@ -2411,7 +2411,7 @@ "example": "20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)" }, "summary": "Popular Pages", - "description": "Popular Pages. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.", + "description": "Popular Pages. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#popular-pages) before a paid request.\n\n", "operationId": "get_similarweb_popular_pages", "parameters": [ { @@ -2609,7 +2609,7 @@ "example": "20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)" }, "summary": "Website Subdomains", - "description": "Website Subdomains. Response follows the SimilarWeb v5 envelope (meta + data).", + "description": "Website Subdomains. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 2 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#subdomains) before a paid request.\n\n", "operationId": "get_similarweb_subdomains", "parameters": [ { @@ -2797,7 +2797,7 @@ "example": "20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)" }, "summary": "Keyword Competitors", - "description": "Keyword Competitors. Response follows the SimilarWeb v5 envelope (meta + data).", + "description": "Keyword Competitors. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.03 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.03 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.03 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#keyword-competitors) before a paid request.\n\n", "operationId": "get_similarweb_keyword_competitors", "parameters": [ { @@ -2992,7 +2992,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "Website Keywords", - "description": "Website Keywords. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 3 monthly buckets. Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.", + "description": "Website Keywords. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 3 monthly buckets. Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-keywords) before a paid request.\n\n", "operationId": "get_similarweb_keywords", "parameters": [ { @@ -3232,7 +3232,7 @@ "example": "20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)" }, "summary": "SERP Players - Clicks over time", - "description": "SERP Players - Clicks over time. Response follows the SimilarWeb v5 envelope (meta + data).", + "description": "SERP Players - Clicks over time. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.02 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.02 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.02 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#serp-players-timeseries) before a paid request.\n\n", "operationId": "get_similarweb_serp_players_timeseries", "parameters": [ { @@ -3393,7 +3393,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "SERP Players - Aggregated", - "description": "SERP Players - Aggregated. Response follows the SimilarWeb v5 envelope (meta + data).", + "description": "SERP Players - Aggregated. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.07 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.07 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.07 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#serp-players-aggregated) before a paid request.\n\n", "operationId": "get_similarweb_serp_players_aggregated", "parameters": [ { @@ -3584,7 +3584,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "Landing Pages", - "description": "Landing Pages. Response follows the SimilarWeb v5 envelope (meta + data).", + "description": "Landing Pages. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#landing-pages) before a paid request.\n\n", "operationId": "get_similarweb_landing_pages", "parameters": [ { @@ -3812,7 +3812,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Website Traffic Snapshot", - "description": "Latest-month traffic snapshot for a domain: visits plus core engagement metrics (average visit duration, bounce rate, pages per visit) in a single object. The most recent available month is selected automatically and echoed in meta.start_date / meta.end_date.", + "description": "Latest-month traffic snapshot for a domain: visits plus core engagement metrics (average visit duration, bounce rate, pages per visit) in a single object. The most recent available month is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled schedule example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. Treat the published example as the documented exposure and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-traffic-snapshot) before a paid request.\n\n", "operationId": "get_similarweb_website_traffic_snapshot", "parameters": [ { @@ -3952,7 +3952,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Website Traffic Trend", - "description": "Monthly traffic time series for a domain over the recent available window (data.points, one entry per month). The window is selected automatically and echoed in meta.start_date / meta.end_date.", + "description": "Monthly traffic time series for a domain over the recent available window (data.points, one entry per month). The window is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled schedule example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. Treat the published example as the documented exposure and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-traffic-trend) before a paid request.\n\n", "operationId": "get_similarweb_website_traffic_trend", "parameters": [ { @@ -4127,7 +4127,7 @@ "example": "10 rows = 30 credits ($3.00); limit=5 = 15 credits ($1.50)" }, "summary": "Website Top Geographies", - "description": "Top countries by share of a domain's traffic for the latest available month (data.countries, up to 10 rows with country_code, country_name, share and visits). Geography coverage is worldwide (ww) and fixed: a country parameter is not accepted for this endpoint.", + "description": "Top countries by share of a domain's traffic for the latest available month (data.countries, up to 10 rows with country_code, country_name, share and visits). Geography coverage is worldwide (ww) and fixed: a country parameter is not accepted for this endpoint.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 10 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 10`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 10 rows are billed. Published maximum-exposure example: `10 rows = 30 credits ($3.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`.\n\n**IMPORTANT:** This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-top-geographies) before a paid request.\n\n", "operationId": "get_similarweb_website_top_geographies", "parameters": [ { diff --git a/scripts/check_similarweb_pricing.py b/scripts/check_similarweb_pricing.py new file mode 100644 index 00000000..510a1f29 --- /dev/null +++ b/scripts/check_similarweb_pricing.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python3 +"""Validate that SimilarWeb's human and machine pricing surfaces stay aligned.""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +from typing import Any + +import yaml + +from generate_similarweb_pricing_docs import ( + EXPECTED_OPERATION_IDS, + GUIDE_PATH, + ROOT, + SOURCE_PATH, + ZH_GUIDE_PATH, + check_outputs, + category, + collect_operations, + expected_outputs, + load_source, + provider_controlled_drivers, +) + + +LLMS_PATH = ROOT / "llms.txt" +NAV_PATH = ROOT / "docs.json" +PRICING_OVERVIEW_PATH = ROOT / "guides" / "pricing.mdx" +PER_CALL_PATH = ROOT / "guides" / "pricing" / "per-call-api-pricing.mdx" +ZH_PRICING_OVERVIEW_PATH = ROOT / "zh" / "guides" / "pricing.mdx" +ZH_PER_CALL_PATH = ROOT / "zh" / "guides" / "pricing" / "per-call-api-pricing.mdx" + + +def fail(message: str) -> None: + raise SystemExit(f"pricing contract check failed: {message}") + + +def contains(value: Any, wanted: str) -> bool: + if value == wanted: + return True + if isinstance(value, list): + return any(contains(item, wanted) for item in value) + if isinstance(value, dict): + return any(contains(item, wanted) for item in value.values()) + return False + + +def check_checked_in_surfaces(source: dict[str, Any]) -> None: + stale = check_outputs(expected_outputs(source)) + if stale: + paths = ", ".join(str(path.relative_to(ROOT)) for path in stale) + fail(f"generated surfaces are stale: {paths}; run generate_similarweb_pricing_docs.py --write") + + for guide in (GUIDE_PATH, ZH_GUIDE_PATH): + content = guide.read_text(encoding="utf-8") + if "IMPORTANT" not in content or "x-aisa-pricing" not in content: + fail(f"{guide.relative_to(ROOT)} lacks the required machine-derived warning") + + operations = collect_operations(source) + for operation in operations: + endpoint = ROOT / "api-reference" / "similarweb" / f"{operation.endpoint_slug}.mdx" + if not endpoint.exists(): + fail(f"{operation.operation_id} has no endpoint documentation page") + for guide in (GUIDE_PATH, ZH_GUIDE_PATH): + content = guide.read_text(encoding="utf-8") + if f'' not in content: + fail(f"{guide.relative_to(ROOT)} has no anchor for {operation.operation_id}") + + description = source["paths"][operation.path]["get"]["description"] + uncontrolled = provider_controlled_drivers(operation) + if category(operation) == "rows" and uncontrolled: + if "does not accept `limit`" not in description: + fail(f"{operation.operation_id} does not disclose that limit is unavailable") + if "; limit=" in description: + fail(f"{operation.operation_id} renders a non-callable limit example as request syntax") + if category(operation) == "dimensions" and uncontrolled and not operation.parameter_names.intersection({"metrics", "start_date", "end_date"}): + if "provider-controlled dimensions" not in description: + fail(f"{operation.operation_id} does not disclose provider-controlled pricing dimensions") + + llms = LLMS_PATH.read_text(encoding="utf-8") + if "guides/pricing/similarweb" not in llms or "SimilarWeb Pricing & Cost Control" not in llms: + fail("llms.txt does not route agents to SimilarWeb pricing guidance") + similar_sites = next(operation for operation in operations if operation.operation_id == "get_similarweb_similar_sites") + endpoint_url = f"https://aisa.one/docs{similar_sites.endpoint_url}" + if endpoint_url not in llms: + fail("llms.txt SimilarWeb API family link does not resolve to the SimilarSites endpoint page") + + navigation = json.loads(NAV_PATH.read_text(encoding="utf-8")) + for slug in ("guides/pricing/similarweb", "zh/guides/pricing/similarweb"): + if not contains(navigation, slug): + fail(f"docs navigation does not include {slug}") + + english_overview = PRICING_OVERVIEW_PATH.read_text(encoding="utf-8") + chinese_overview = ZH_PRICING_OVERVIEW_PATH.read_text(encoding="utf-8") + if "All non-LLM APIs use a fixed per-request billing model." in english_overview: + fail("English pricing overview still classifies every non-LLM API as fixed-price") + if "所有非 LLM API 使用固定的按请求计费模型。" in chinese_overview: + fail("Chinese pricing overview still classifies every non-LLM API as fixed-price") + + for path in (PRICING_OVERVIEW_PATH, PER_CALL_PATH, ZH_PRICING_OVERVIEW_PATH, ZH_PER_CALL_PATH): + if "similarweb" not in path.read_text(encoding="utf-8").lower(): + fail(f"{path.relative_to(ROOT)} does not link to SimilarWeb pricing guidance") + + +def check_consolidated_openapi(source: dict[str, Any], generated_path: Path) -> None: + with generated_path.open(encoding="utf-8") as stream: + generated = yaml.safe_load(stream) + if not isinstance(generated, dict) or not isinstance(generated.get("paths"), dict): + fail("generated OpenAPI has no paths object") + + for operation in collect_operations(source): + expected = operation.pricing + actual = generated["paths"].get(operation.path, {}).get("get", {}).get("x-aisa-pricing") + if actual != expected: + fail(f"generated OpenAPI did not preserve x-aisa-pricing for {operation.path}") + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument( + "--generated", + type=Path, + help="optional consolidated OpenAPI YAML to compare with the source", + ) + args = parser.parse_args() + + source = load_source() + operations = collect_operations(source) + if len(operations) != len(EXPECTED_OPERATION_IDS): + fail("unexpected SimilarWeb operation inventory") + check_checked_in_surfaces(source) + if args.generated: + check_consolidated_openapi(source, args.generated) + print(f"pricing contract check passed: {len(operations)} SimilarWeb operations") + + +if __name__ == "__main__": + main() diff --git a/scripts/generate_similarweb_pricing_docs.py b/scripts/generate_similarweb_pricing_docs.py new file mode 100644 index 00000000..d3e71f2c --- /dev/null +++ b/scripts/generate_similarweb_pricing_docs.py @@ -0,0 +1,595 @@ +#!/usr/bin/env python3 +"""Generate SimilarWeb's human-readable pricing surfaces from OpenAPI metadata. + +`x-aisa-pricing` is the only source of monetary facts. This script renders the +English and Chinese pricing guides plus the pricing disclosure shown on each +SimilarWeb endpoint page. Run with ``--write`` when the metadata changes and +``--check`` in CI to prevent a hand-edited guide or endpoint description from +drifting from the machine-readable contract. +""" + +from __future__ import annotations + +import argparse +import copy +import json +import re +from dataclasses import dataclass +from pathlib import Path +from typing import Any + + +ROOT = Path(__file__).resolve().parents[1] +SOURCE_PATH = ROOT / "openapi" / "similarweb.json" +GUIDE_PATH = ROOT / "guides" / "pricing" / "similarweb.mdx" +ZH_GUIDE_PATH = ROOT / "zh" / "guides" / "pricing" / "similarweb.mdx" +API_REFERENCE_DIR = ROOT / "api-reference" / "similarweb" + +EXPECTED_OPERATION_IDS = frozenset( + { + "get_similarweb_traffic_engagement", + "get_similarweb_ranking", + "get_similarweb_ppc_spend", + "get_similarweb_top_sites_ranking", + "get_similarweb_marketing_channel_sources_legacy", + "get_similarweb_referrals", + "get_similarweb_ad_networks", + "get_similarweb_similar_sites", + "get_similarweb_demographics", + "get_similarweb_deduplicated_audience", + "get_similarweb_audience_interest", + "get_similarweb_audience_overlap", + "get_similarweb_technologies", + "get_similarweb_popular_pages", + "get_similarweb_subdomains", + "get_similarweb_keyword_competitors", + "get_similarweb_keywords", + "get_similarweb_serp_players_timeseries", + "get_similarweb_serp_players_aggregated", + "get_similarweb_landing_pages", + "get_similarweb_website_traffic_snapshot", + "get_similarweb_website_traffic_trend", + "get_similarweb_website_top_geographies", + } +) + +DISCLOSURE_START = "" +DISCLOSURE_END = "" +DISCLOSURE_PATTERN = re.compile( + rf"\n*{re.escape(DISCLOSURE_START)}.*?{re.escape(DISCLOSURE_END)}\n*", + re.DOTALL, +) +OPENAPI_REFERENCE_PATTERN = re.compile( + r'^openapi:\s+"openapi/similarweb\.json GET (?P[^"]+)"$', + re.MULTILINE, +) + + +@dataclass(frozen=True) +class Operation: + """A SimilarWeb operation together with its #92 pricing contract.""" + + path: str + operation_id: str + endpoint_slug: str + summary: str + pricing: dict[str, Any] + parameter_names: frozenset[str] + + @property + def anchor(self) -> str: + return self.path.rsplit("/", 1)[-1] + + @property + def endpoint_url(self) -> str: + return f"/api-reference/similarweb/{self.endpoint_slug}" + + +def fail(message: str) -> None: + raise ValueError(f"SimilarWeb pricing generation failed: {message}") + + +def load_source() -> dict[str, Any]: + with SOURCE_PATH.open(encoding="utf-8") as stream: + source = json.load(stream) + if not isinstance(source, dict): + fail("openapi/similarweb.json is not an object") + return source + + +def validate_pricing(path: str, pricing: Any) -> dict[str, Any]: + if not isinstance(pricing, dict): + fail(f"{path} has no x-aisa-pricing object") + + required = { + "model", + "currency", + "credit_price_usd", + "credit_formula", + "credit_rate", + "cost_drivers", + "cost_tier", + "example", + } + missing = sorted(required - pricing.keys()) + if missing: + fail(f"{path} is missing pricing keys: {', '.join(missing)}") + if pricing["model"] != "per_credit": + fail(f"{path} has unsupported pricing model {pricing['model']!r}") + if pricing["currency"] != "USD": + fail(f"{path} must use USD") + if not isinstance(pricing["credit_price_usd"], (int, float)) or pricing["credit_price_usd"] <= 0: + fail(f"{path} must have a positive credit_price_usd") + for field in ("credit_formula", "credit_rate", "cost_tier", "example"): + if not isinstance(pricing[field], str) or not pricing[field].strip(): + fail(f"{path} has an empty {field}") + if not isinstance(pricing["cost_drivers"], list) or not pricing["cost_drivers"]: + fail(f"{path} needs at least one cost driver") + for driver in pricing["cost_drivers"]: + if not isinstance(driver, dict): + fail(f"{path} has a non-object cost driver") + for field in ("param", "effect"): + if not isinstance(driver.get(field), str) or not driver[field].strip(): + fail(f"{path} has an invalid cost driver {field}") + return pricing + + +def api_reference_pages() -> dict[str, str]: + pages: dict[str, str] = {} + for page in API_REFERENCE_DIR.glob("*.mdx"): + match = OPENAPI_REFERENCE_PATTERN.search(page.read_text(encoding="utf-8")) + if not match: + continue + path = match.group("path") + if path in pages: + fail(f"duplicate endpoint page for {path}") + pages[path] = page.stem + return pages + + +def collect_operations(source: dict[str, Any]) -> list[Operation]: + paths = source.get("paths") + if not isinstance(paths, dict): + fail("source OpenAPI has no paths object") + + reference_pages = api_reference_pages() + operations: list[Operation] = [] + seen_ids: set[str] = set() + for path, item in paths.items(): + if not isinstance(item, dict): + continue + operation = item.get("get") + if not isinstance(operation, dict) or "x-aisa-pricing" not in operation: + continue + + operation_id = operation.get("operationId") + summary = operation.get("summary") + description = operation.get("description") + if not isinstance(operation_id, str) or not operation_id: + fail(f"{path} has no operationId") + if not isinstance(summary, str) or not summary: + fail(f"{path} has no summary") + if not isinstance(description, str) or not description: + fail(f"{path} has no description") + if operation_id in seen_ids: + fail(f"duplicate operationId {operation_id}") + seen_ids.add(operation_id) + endpoint_slug = reference_pages.get(path) + if not endpoint_slug: + fail(f"{path} has no API reference page") + + parameters = operation.get("parameters", []) + if not isinstance(parameters, list): + fail(f"{path} has invalid parameters") + parameter_names = frozenset( + parameter["name"] + for parameter in parameters + if isinstance(parameter, dict) and isinstance(parameter.get("name"), str) + ) + operations.append( + Operation( + path=path, + operation_id=operation_id, + endpoint_slug=endpoint_slug, + summary=summary, + pricing=validate_pricing(path, operation["x-aisa-pricing"]), + parameter_names=parameter_names, + ) + ) + + found_ids = {operation.operation_id for operation in operations} + missing = sorted(EXPECTED_OPERATION_IDS - found_ids) + unexpected = sorted(found_ids - EXPECTED_OPERATION_IDS) + if missing or unexpected: + details = [] + if missing: + details.append(f"missing operation IDs: {', '.join(missing)}") + if unexpected: + details.append(f"unexpected operation IDs: {', '.join(unexpected)}") + fail("; ".join(details)) + if len(operations) != len(EXPECTED_OPERATION_IDS): + fail(f"expected exactly {len(EXPECTED_OPERATION_IDS)} pricing operations, found {len(operations)}") + return operations + + +def category(operation: Operation) -> str: + driver_names = {driver["param"] for driver in operation.pricing["cost_drivers"]} + if driver_names == {"(none)"}: + return "fixed" + if "limit" in driver_names: + return "rows" + return "dimensions" + + +def price(value: float | int) -> str: + return f"${value:.2f}" + + +def drivers_en(operation: Operation) -> str: + return "; ".join( + f"`{driver['param']}`: {driver['effect']}" + for driver in operation.pricing["cost_drivers"] + ) + + +def effect_zh(effect: str) -> str: + exact = { + "number of metrics requested": "请求的指标数量", + "number of months in the date window": "日期范围内的月份数", + "flat per-request credit charge": "每次请求固定 credit 费用", + } + if effect in exact: + return exact[effect] + row_match = re.fullmatch( + r"charge scales with rows returned at (.+) credit/row; at most (\d+) rows are billed", + effect, + ) + if row_match: + return f"按返回行数以 {row_match.group(1)} credit/行累积计费,最多计 {row_match.group(2)} 行" + fail(f"cannot localize an unknown cost-driver effect: {effect!r}") + + +def drivers_zh(operation: Operation) -> str: + return ";".join( + f"`{driver['param']}`:{effect_zh(driver['effect'])}" + for driver in operation.pricing["cost_drivers"] + ) + + +def driver_is_controllable(operation: Operation, driver_name: str) -> bool: + if driver_name == "periods": + return {"start_date", "end_date"}.issubset(operation.parameter_names) + return driver_name in operation.parameter_names + + +def controllable_drivers(operation: Operation) -> list[str]: + return [ + driver["param"] + for driver in operation.pricing["cost_drivers"] + if driver["param"] != "(none)" and driver_is_controllable(operation, driver["param"]) + ] + + +def provider_controlled_drivers(operation: Operation) -> list[str]: + return [ + driver["param"] + for driver in operation.pricing["cost_drivers"] + if driver["param"] != "(none)" and not driver_is_controllable(operation, driver["param"]) + ] + + +def display_example_en(operation: Operation) -> tuple[str, str]: + raw_example = operation.pricing["example"] + uncontrolled = provider_controlled_drivers(operation) + if category(operation) == "rows" and uncontrolled: + exposure, _, _ = raw_example.partition("; limit=") + return ( + "Published maximum-exposure example", + f"`{exposure}`. The source's `limit=...` text is a metering illustration only; " + "this endpoint does not accept `limit`.", + ) + if category(operation) == "dimensions" and uncontrolled: + names = ", ".join(f"`{name}`" for name in uncontrolled) + return ( + "Provider-controlled schedule example", + f"`{raw_example.rstrip('.')}`. {names} are provider-controlled for this endpoint, not caller-selectable request parameters.", + ) + return "Current schedule example", f"`{raw_example}`" + + +def display_example_zh(operation: Operation) -> tuple[str, str]: + raw_example = operation.pricing["example"] + uncontrolled = provider_controlled_drivers(operation) + if category(operation) == "rows" and uncontrolled: + exposure, _, _ = raw_example.partition("; limit=") + return ( + "公开最大成本暴露示例", + f"`{exposure}`。源数据中的 `limit=...` 仅用于说明计量,不是该端点接受的 `limit` 参数。", + ) + if category(operation) == "dimensions" and uncontrolled: + names = "、".join(f"`{name}`" for name in uncontrolled) + return ( + "Provider 控制的计价表示例", + f"`{raw_example.rstrip('.')}`。对于该端点,{names} 由 provider 控制,不能由调用方作为请求参数选择。", + ) + return "当前公开示例", f"`{raw_example}`" + + +def control_en(operation: Operation) -> str: + operation_category = category(operation) + if operation_category == "fixed": + return "The published credit charge is fixed for this request type." + if operation_category == "rows": + if "limit" in operation.parameter_names: + return "Use the smallest meaningful `limit`; returned rows drive the credit cost." + return ( + "This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce " + "its cost with `limit`; use the documented example and cap as the exposure of one accepted request." + ) + controllable = controllable_drivers(operation) + uncontrolled = provider_controlled_drivers(operation) + if not controllable: + names = ", ".join(f"`{name}`" for name in uncontrolled) + return ( + f"The formula includes provider-controlled dimensions ({names}) that are not accepted request parameters. " + "Treat the published example as the documented exposure and obtain a budget decision before execution." + ) + control_names = ", ".join( + "the `start_date`/`end_date` range" if name == "periods" else f"`{name}`" + for name in controllable + ) + result = f"Cost varies with {control_names}; set the smallest required scope and obtain a budget decision before execution." + if uncontrolled: + names = ", ".join(f"`{name}`" for name in uncontrolled) + result += f" {names} remain provider-controlled." + return result + + +def control_zh(operation: Operation) -> str: + operation_category = category(operation) + if operation_category == "fixed": + return "该类请求的公开 credit 费用是固定的。" + if operation_category == "rows": + if "limit" in operation.parameter_names: + return "返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。" + return ( + "该端点按返回行数计费,但没有已记录的 `limit` 参数。不要承诺调用方可通过 `limit` 降低费用;" + "应把公开示例和上限视为一次被接受请求的成本暴露。" + ) + controllable = controllable_drivers(operation) + uncontrolled = provider_controlled_drivers(operation) + if not controllable: + names = "、".join(f"`{name}`" for name in uncontrolled) + return ( + f"公式包含由 provider 控制且不能作为请求参数传入的维度({names})。" + "请把公开示例视为已记录的成本暴露,并在执行前取得预算确认。" + ) + control_names = "、".join( + "`start_date`/`end_date` 日期范围" if name == "periods" else f"`{name}`" + for name in controllable + ) + result = f"费用会随 {control_names} 变化;执行前请缩小到必要范围并取得预算确认。" + if uncontrolled: + names = "、".join(f"`{name}`" for name in uncontrolled) + result += f" {names} 仍由 provider 控制。" + return result + + +def mode_en(operation: Operation) -> str: + return { + "fixed": "fixed per request", + "rows": "returned-row credit pricing", + "dimensions": "request-dimension credit pricing", + }[category(operation)] + + +def mode_zh(operation: Operation) -> str: + return { + "fixed": "固定每请求 credit 计费", + "rows": "按返回行数 credit 计费", + "dimensions": "按请求维度 credit 计费", + }[category(operation)] + + +def generated_disclosure(operation: Operation) -> str: + pricing = operation.pricing + example_label, example = display_example_en(operation) + return "\n".join( + ( + DISCLOSURE_START, + "**Pricing (generated from `x-aisa-pricing`):** " + f"`{pricing['credit_rate']}` at `{price(pricing['credit_price_usd'])}` per credit. " + f"Formula: `{pricing['credit_formula']}`. Cost drivers: {drivers_en(operation)}. " + f"{example_label}: {example}", + "", + f"**IMPORTANT:** {control_en(operation)} " + f"Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#{operation.anchor}) " + "before a paid request.", + DISCLOSURE_END, + ) + ) + + +def strip_generated_disclosure(description: str) -> str: + matches = list(DISCLOSURE_PATTERN.finditer(description)) + if len(matches) > 1: + fail("an operation description contains multiple generated pricing disclosures") + return DISCLOSURE_PATTERN.sub("", description).rstrip() + + +def render_source(source: dict[str, Any], operations: list[Operation]) -> str: + rendered = copy.deepcopy(source) + for operation in operations: + target = rendered["paths"][operation.path]["get"] + base_description = strip_generated_disclosure(target["description"]) + target["description"] = f"{base_description}\n\n{generated_disclosure(operation)}\n" + + source_metadata = { + operation.path: operation.pricing for operation in collect_operations(source) + } + rendered_metadata = { + operation.path: rendered["paths"][operation.path]["get"]["x-aisa-pricing"] + for operation in operations + } + if rendered_metadata != source_metadata: + fail("generation attempted to change x-aisa-pricing metadata") + return json.dumps(rendered, indent=2, ensure_ascii=False) + "\n" + + +def operation_section_en(operation: Operation) -> str: + pricing = operation.pricing + example_label, example = display_example_en(operation) + return "\n".join( + ( + f'', + f"### [{operation.summary}]({operation.endpoint_url})", + "", + f"- **Pricing mode:** {mode_en(operation)}.", + f"- **Credit rate:** `{pricing['credit_rate']}` at `{price(pricing['credit_price_usd'])}` per credit.", + f"- **Formula:** `{pricing['credit_formula']}`.", + f"- **Cost drivers:** {drivers_en(operation)}.", + f"- **{example_label}:** {example}", + f"- **Control:** {control_en(operation)}", + "", + ) + ) + + +def operation_section_zh(operation: Operation) -> str: + pricing = operation.pricing + example_label, example = display_example_zh(operation) + return "\n".join( + ( + f'', + f"### [{operation.summary}]({operation.endpoint_url})", + "", + f"- **计费方式:** {mode_zh(operation)}。", + f"- **Credit 费率:** `{pricing['credit_rate']}`,每 credit `{price(pricing['credit_price_usd'])}`。", + f"- **公式:** `{pricing['credit_formula']}`。", + f"- **费用驱动因素:** {drivers_zh(operation)}。", + f"- **{example_label}:** {example}", + f"- **控制方式:** {control_zh(operation)}", + "", + ) + ) + + +def render_guide_en(operations: list[Operation]) -> str: + groups = ( + ("dimensions", "Request-dimension pricing"), + ("rows", "Returned-row pricing"), + ("fixed", "Fixed per-request pricing"), + ) + parts = [ + "---", + "title: SimilarWeb Pricing & Cost Control", + "excerpt: >-", + " Machine-derived SimilarWeb credit formulas, examples, and cost controls", + " for people and agents before a paid request.", + "---", + "", + "SimilarWeb is a paid data API with credit-based pricing. Its catalog display value is not always a fixed, request-specific quote.", + "", + "", + " **IMPORTANT:** Before a paid SimilarWeb request, read the matching endpoint disclosure below, state the cost driver and documented exposure, and use the smallest scope that answers the task. For request-dimension pricing, obtain a budget decision before execution.", + "", + "", + "This page is generated from each endpoint's `x-aisa-pricing` object in the [machine-readable OpenAPI](https://aisa.one/openapi.yaml). It intentionally does not maintain a second hand-authored rate schedule.", + "", + "## How settlement works", + "", + "SimilarWeb uses a two-phase credit model: the gateway can report a pre-authorization estimate in `X-AISA-Estimated-Credits`, then reports settled usage in `X-AISA-Accounted-Credits` and `X-AISA-Price-USD`. The provider-level API contract says that only successful, non-empty responses are billed. These formulas and examples describe the published schedule; they are not a server-authoritative quote endpoint.", + "", + "Do not treat a catalog `pricing.normal` value of `0` as a free SimilarWeb request.", + "", + ] + for group, heading in groups: + members = [operation for operation in operations if category(operation) == group] + if not members: + continue + parts.extend((f"## {heading}", "")) + for operation in members: + parts.append(operation_section_en(operation).rstrip()) + parts.append("") + return "\n".join(parts).rstrip() + "\n" + + +def render_guide_zh(operations: list[Operation]) -> str: + groups = ( + ("dimensions", "按请求维度计费"), + ("rows", "按返回行数计费"), + ("fixed", "固定每请求计费"), + ) + parts = [ + "---", + "title: SimilarWeb 价格与成本控制", + "excerpt: >-", + " 从机器可读合同自动生成的 SimilarWeb credit 公式、示例与成本控制说明,", + " 供人和 Agent 在付费请求前使用。", + "---", + "", + "SimilarWeb 是付费数据 API,采用 credit 计费。目录展示值并不总是某次请求的固定、精确报价。", + "", + "", + " **重要(IMPORTANT):** 发起付费 SimilarWeb 请求前,请阅读下面对应端点的价格说明,向用户说明费用驱动因素和已记录的成本暴露,并选择足以回答问题的最小范围。对于按请求维度计费的端点,执行前必须取得预算确认。", + "", + "", + "本页从 [机器可读 OpenAPI](https://aisa.one/openapi.yaml) 中每个端点的 `x-aisa-pricing` 对象自动生成,故意不维护第二份手写费率表。", + "", + "## 如何结算", + "", + "SimilarWeb 使用两阶段 credit 模型:网关可以在 `X-AISA-Estimated-Credits` 中返回预授权估算,然后在 `X-AISA-Accounted-Credits` 和 `X-AISA-Price-USD` 中报告最终结算用量。provider 级 API 合同说明只有成功且非空的响应会计费。这里的公式和示例描述公开计价表,并不是服务端权威的报价接口。", + "", + "不要把目录中的 `pricing.normal = 0` 当成 SimilarWeb 免费调用。", + "", + ] + for group, heading in groups: + members = [operation for operation in operations if category(operation) == group] + if not members: + continue + parts.extend((f"## {heading}", "")) + for operation in members: + parts.append(operation_section_zh(operation).rstrip()) + parts.append("") + return "\n".join(parts).rstrip() + "\n" + + +def expected_outputs(source: dict[str, Any]) -> dict[Path, str]: + operations = collect_operations(source) + return { + SOURCE_PATH: render_source(source, operations), + GUIDE_PATH: render_guide_en(operations), + ZH_GUIDE_PATH: render_guide_zh(operations), + } + + +def check_outputs(outputs: dict[Path, str]) -> list[Path]: + return [path for path, expected in outputs.items() if not path.exists() or path.read_text(encoding="utf-8") != expected] + + +def main() -> None: + parser = argparse.ArgumentParser() + mode = parser.add_mutually_exclusive_group(required=True) + mode.add_argument("--write", action="store_true", help="write generated pricing surfaces") + mode.add_argument("--check", action="store_true", help="fail if generated pricing surfaces are stale") + args = parser.parse_args() + + outputs = expected_outputs(load_source()) + stale = check_outputs(outputs) + if args.check: + if stale: + rendered_paths = ", ".join(str(path.relative_to(ROOT)) for path in stale) + raise SystemExit(f"SimilarWeb pricing surfaces are stale: {rendered_paths}. Run --write.") + print(f"SimilarWeb pricing surfaces are current: {len(EXPECTED_OPERATION_IDS)} operations") + return + + for path in stale: + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(outputs[path], encoding="utf-8") + print(f"updated {path.relative_to(ROOT)}") + if not stale: + print(f"SimilarWeb pricing surfaces already current: {len(EXPECTED_OPERATION_IDS)} operations") + + +if __name__ == "__main__": + main() diff --git a/zh/evaluate/pricing.mdx b/zh/evaluate/pricing.mdx index 87d8397d..f23f9838 100644 --- a/zh/evaluate/pricing.mdx +++ b/zh/evaluate/pricing.mdx @@ -11,6 +11,7 @@ AIsa 对模型推理和计费型 API 能力采用按量计费。具体价格取 - [AI 模型价格](/zh/guides/pricing/ai-model-pricing-llm-inference):模型计费说明。 - [按次调用 API 价格](/zh/guides/pricing/per-call-api-pricing):API 计费说明。 +- [SimilarWeb 价格与成本控制](/zh/guides/pricing/similarweb):SimilarWeb 的公式化端点价格。 - [钱包与支付](/zh/guides/pricing/wallet):充值和余额行为。 - [用量日志](/zh/guides/dashboard/usage-logs):账户的实际用量。 - 实时模型目录或具体 API 页面:当前能力的上下文信息。 diff --git a/zh/guides/pricing.mdx b/zh/guides/pricing.mdx index 73c3dc76..e63f1074 100644 --- a/zh/guides/pricing.mdx +++ b/zh/guides/pricing.mdx @@ -1,15 +1,15 @@ --- title: "AIsa 价格 - LLM 与数据 API 的按量计费" excerpt: >- - AIsa 价格总览:100+ AI 模型按 token 计费,搜索、金融、Twitter 和数据 API 按次调用计费。无订阅费,只为实际使用付费。 + AIsa 价格总览:100+ AI 模型按 token 计费,数据 API 可能是固定按次计费或公式计费。无订阅费,只为实际使用付费。 --- AIsa 使用按量计费系统。费用会根据你使用的 API 类型计算。 -主要有两种计费模型: +主要有两类计费方式: 1. **AI Model(LLM)价格:** 按 token 计费。 -2. **按次调用 API 价格:** 按请求计费。 +2. **数据 API 价格:** 许多 API 按固定请求计费;部分 provider 按请求维度或返回行数使用 credit 公式计费。 本页提供两种计费模型的高层概览,并链接到对应的详细价格页面。 @@ -38,15 +38,15 @@ AI 模型 API 根据 token 用量计费。 完整模型价格表和详细计费说明请查看 [AI 模型价格](/zh/guides/pricing/ai-model-pricing-llm-inference)。 -## 2. 按次调用 API 价格 +## 2. 数据 API 价格 -所有非 LLM API 使用固定的按请求计费模型。 +许多非 LLM API 使用固定的按请求计费模型;部分数据 provider 则使用可变的 credit 计费模型。 ![AIsa 上的 Twitter API 页面,每个 endpoint 都标注了固定的按次调用价格](/images/bdd00244-twitter-api-per-call.png) -每个 API 页面都会逐个列出 endpoint 及其价格 —— 以上面的 Twitter 为例,`/apis/v1/twitter/user/last_tweets` 每次调用 \$0.0036,`/apis/v1/twitter/user/followers` 每次调用 \$0.036。 +对于固定价格 API,每个 API 页面都会逐个列出 endpoint 及其价格 —— 以上面的 Twitter 为例,`/apis/v1/twitter/user/last_tweets` 每次调用 \$0.0036,`/apis/v1/twitter/user/followers` 每次调用 \$0.036。 -对某个 endpoint 的每次成功请求都会产生预设费用,与响应大小无关。 +对于这些 API,某个 endpoint 的每次成功请求都会产生预设费用,与响应大小无关。 该计费模型适用于这类 API: @@ -57,16 +57,20 @@ AI 模型 API 根据 token 用量计费。 * Twitter APIs。 * 其他结构化数据和检索服务。 -如需查看 endpoint 级别的价格细节和计费行为,请查看 [按次调用 API 价格](/zh/guides/pricing/per-call-api-pricing)。 +如需查看固定按次计费 API 的 endpoint 级价格细节和计费行为,请查看[按次调用 API 价格](/zh/guides/pricing/per-call-api-pricing)。 + +### SimilarWeb:公式计费 + +SimilarWeb 是付费数据 API,使用 credit 公式。不同端点的费用可能固定、由请求维度决定,或由返回行数决定。发起付费请求前,请阅读 [SimilarWeb 价格与成本控制](/zh/guides/pricing/similarweb);页面会展示当前公式、费用驱动因素、示例和端点级控制方式。 ## 如何选择正确的计费模型 如果你的 API 请求: * 使用语言模型生成文本 → **适用按 token 计费**。 -* 检索结构化数据或执行搜索 → **适用按次调用计费**。 +* 检索结构化数据或执行搜索 → **先阅读对应 API 的计费模型**;它可能是固定按次计费,也可能是公式计费。 -模型目录页会显示每个模型的按 token 价格,每个 API 页面会显示各 endpoint 的按次调用价格。 +模型目录页会显示每个模型的按 token 价格。固定价格 API 页面会显示按次价格;公式计费 API 会在端点文档中展示公式和成本控制方式。 ## 用量追踪和透明度 diff --git a/zh/guides/pricing/per-call-api-pricing.mdx b/zh/guides/pricing/per-call-api-pricing.mdx index 899b6bae..999af958 100644 --- a/zh/guides/pricing/per-call-api-pricing.mdx +++ b/zh/guides/pricing/per-call-api-pricing.mdx @@ -1,14 +1,18 @@ --- -title: "按次调用 API 价格 - 搜索、金融、Twitter 与数据 API" +title: "按次调用 API 价格 - 固定价格的搜索、金融、Twitter 与数据 API" excerpt: >- - AIsa 非 LLM API 的固定按请求价格,包括网页搜索、金融数据、Twitter、YouTube 和学术 endpoint。简单的固定费率计费,无需计算 token。 + 适用的 AIsa 数据 API 的固定按请求价格,包括网页搜索、金融数据、Twitter、YouTube 和学术 endpoint。可变费用数据 API 有单独的计费说明。 --- -本页说明 AIsa 中所有非 LLM API 的计费模型。 +本页说明 AIsa 中适用的非 LLM API 的固定价格计费模型。 + + + **重要(IMPORTANT):** 本页不代表所有数据 API 都是固定价格。SimilarWeb 端点可能是固定计费、按返回行数计费,或按请求维度计费。发起付费 SimilarWeb 请求前,请先阅读 [SimilarWeb 价格与成本控制](/zh/guides/pricing/similarweb)。 + ![AIsa 上的 Tavily Search API 页面,每个 endpoint 都标注了固定的按次调用价格](/images/6bd32ad1-tavily-search-per-call.png) -这些 API 使用 **固定按请求计费模型**。对某个 endpoint 的每次成功请求都会产生预设费用,与响应大小、token 数量或处理时间无关。以上面的 Tavily Search 为例,crawl、extract、map 和 search 每次调用都是 \$0.0096,与返回的数据量无关。 +这些适用的 API 使用 **固定按请求计费模型**。对某个 endpoint 的每次成功请求都会产生预设费用,与响应大小、token 数量或处理时间无关。以上面的 Tavily Search 为例,crawl、extract、map 和 search 每次调用都是 \$0.0096,与返回的数据量无关。 按次调用价格适用于这类 API: @@ -46,7 +50,7 @@ excerpt: >- 每个按次调用 API endpoint 都有自己的定义价格。 -在每个 API 页面中,每个 endpoint 条目会显示: +在每个固定价格 API 页面中,每个 endpoint 条目会显示: * HTTP 方法和 endpoint 名称。 * API path。 @@ -108,6 +112,6 @@ Group 级别的价格规则或 ratio(如果已配置)会在计费时自动 * 所有价格均以 USD 标价。 * 每次成功 API 请求都会触发计费。 * 这些 endpoint 不使用按 token 计费。 -* 响应大小不会影响费用。 +* 本页涵盖的固定价格 API 不会因响应大小改变费用。 * 随着 endpoint 演进,价格可能变化。 * 请以各 API 页面上的最新价格为准。 diff --git a/zh/guides/pricing/similarweb.mdx b/zh/guides/pricing/similarweb.mdx new file mode 100644 index 00000000..aff7b354 --- /dev/null +++ b/zh/guides/pricing/similarweb.mdx @@ -0,0 +1,256 @@ +--- +title: SimilarWeb 价格与成本控制 +excerpt: >- + 从机器可读合同自动生成的 SimilarWeb credit 公式、示例与成本控制说明, + 供人和 Agent 在付费请求前使用。 +--- + +SimilarWeb 是付费数据 API,采用 credit 计费。目录展示值并不总是某次请求的固定、精确报价。 + + + **重要(IMPORTANT):** 发起付费 SimilarWeb 请求前,请阅读下面对应端点的价格说明,向用户说明费用驱动因素和已记录的成本暴露,并选择足以回答问题的最小范围。对于按请求维度计费的端点,执行前必须取得预算确认。 + + +本页从 [机器可读 OpenAPI](https://aisa.one/openapi.yaml) 中每个端点的 `x-aisa-pricing` 对象自动生成,故意不维护第二份手写费率表。 + +## 如何结算 + +SimilarWeb 使用两阶段 credit 模型:网关可以在 `X-AISA-Estimated-Credits` 中返回预授权估算,然后在 `X-AISA-Accounted-Credits` 和 `X-AISA-Price-USD` 中报告最终结算用量。provider 级 API 合同说明只有成功且非空的响应会计费。这里的公式和示例描述公开计价表,并不是服务端权威的报价接口。 + +不要把目录中的 `pricing.normal = 0` 当成 SimilarWeb 免费调用。 + +## 按请求维度计费 + + +### [Traffic & Engagement](/api-reference/similarweb/get_similarweb-website-traffic-engagement) + +- **计费方式:** 按请求维度 credit 计费。 +- **Credit 费率:** `1 credit / (metric x month)`,每 credit `$0.10`。 +- **公式:** `credits = 1 x metrics x periods`。 +- **费用驱动因素:** `metrics`:请求的指标数量;`periods`:日期范围内的月份数。 +- **当前公开示例:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods.` +- **控制方式:** 费用会随 `metrics`、`start_date`/`end_date` 日期范围 变化;执行前请缩小到必要范围并取得预算确认。 + + +### [Website Ranking](/api-reference/similarweb/get_similarweb-website-ranking) + +- **计费方式:** 按请求维度 credit 计费。 +- **Credit 费率:** `2 credits / (month)`,每 credit `$0.10`。 +- **公式:** `credits = 2 x periods`。 +- **费用驱动因素:** `periods`:日期范围内的月份数。 +- **当前公开示例:** `minimal (1 month) = 2 credits ($0.20); cost grows with periods.` +- **控制方式:** 费用会随 `start_date`/`end_date` 日期范围 变化;执行前请缩小到必要范围并取得预算确认。 + + +### [PPC Spend](/api-reference/similarweb/get_similarweb-website-ppc-spend) + +- **计费方式:** 按请求维度 credit 计费。 +- **Credit 费率:** `1 credit / (month)`,每 credit `$0.10`。 +- **公式:** `credits = 1 x periods`。 +- **费用驱动因素:** `periods`:日期范围内的月份数。 +- **当前公开示例:** `minimal (1 month) = 1 credit ($0.10); cost grows with periods.` +- **控制方式:** 费用会随 `start_date`/`end_date` 日期范围 变化;执行前请缩小到必要范围并取得预算确认。 + + +### [Marketing Channel Sources](/api-reference/similarweb/get_similarweb-website-marketing-channel-sources-legacy) + +- **计费方式:** 按请求维度 credit 计费。 +- **Credit 费率:** `7 credits / (month)`,每 credit `$0.10`。 +- **公式:** `credits = 7 x periods`。 +- **费用驱动因素:** `periods`:日期范围内的月份数。 +- **当前公开示例:** `minimal (1 month) = 7 credits ($0.70); cost grows with periods.` +- **控制方式:** 费用会随 `start_date`/`end_date` 日期范围 变化;执行前请缩小到必要范围并取得预算确认。 + + +### [Deduplicated Audience](/api-reference/similarweb/get_similarweb-website-deduplicated-audience) + +- **计费方式:** 按请求维度 credit 计费。 +- **Credit 费率:** `7 credits / (month)`,每 credit `$0.10`。 +- **公式:** `credits = 7 x periods`。 +- **费用驱动因素:** `periods`:日期范围内的月份数。 +- **当前公开示例:** `minimal (1 month) = 7 credits ($0.70); cost grows with periods.` +- **控制方式:** 费用会随 `start_date`/`end_date` 日期范围 变化;执行前请缩小到必要范围并取得预算确认。 + + +### [Website Traffic Snapshot](/api-reference/similarweb/get_similarweb-website-traffic-snapshot) + +- **计费方式:** 按请求维度 credit 计费。 +- **Credit 费率:** `1 credit / (metric x month)`,每 credit `$0.10`。 +- **公式:** `credits = 1 x metrics x periods`。 +- **费用驱动因素:** `metrics`:请求的指标数量;`periods`:日期范围内的月份数。 +- **Provider 控制的计价表示例:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`。对于该端点,`metrics`、`periods` 由 provider 控制,不能由调用方作为请求参数选择。 +- **控制方式:** 公式包含由 provider 控制且不能作为请求参数传入的维度(`metrics`、`periods`)。请把公开示例视为已记录的成本暴露,并在执行前取得预算确认。 + + +### [Website Traffic Trend](/api-reference/similarweb/get_similarweb-website-traffic-trend) + +- **计费方式:** 按请求维度 credit 计费。 +- **Credit 费率:** `1 credit / (metric x month)`,每 credit `$0.10`。 +- **公式:** `credits = 1 x metrics x periods`。 +- **费用驱动因素:** `metrics`:请求的指标数量;`periods`:日期范围内的月份数。 +- **Provider 控制的计价表示例:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`。对于该端点,`metrics`、`periods` 由 provider 控制,不能由调用方作为请求参数选择。 +- **控制方式:** 公式包含由 provider 控制且不能作为请求参数传入的维度(`metrics`、`periods`)。请把公开示例视为已记录的成本暴露,并在执行前取得预算确认。 + +## 按返回行数计费 + + +### [Top Sites Ranking](/api-reference/similarweb/get_similarweb-website-top-sites-ranking) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `1 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(1 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 1 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [Referrals](/api-reference/similarweb/get_similarweb-website-referrals) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `4 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(4 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 4 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [Ad Networks](/api-reference/similarweb/get_similarweb-website-ad-networks) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `3 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(3 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 3 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [SimilarSites](/api-reference/similarweb/get_similarweb-website-similar-sites) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `5 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(5 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 5 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [Audience Interest](/api-reference/similarweb/get_similarweb-website-audience-interest) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `5 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(5 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 5 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [Audience Overlap](/api-reference/similarweb/get_similarweb-website-audience-overlap) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `2 / row (max 5 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(2 x rows); rows capped at 5`。 +- **费用驱动因素:** `limit`:按返回行数以 2 credit/行累积计费,最多计 5 行。 +- **公开最大成本暴露示例:** `5 rows = 10 credits ($1.00)`。源数据中的 `limit=...` 仅用于说明计量,不是该端点接受的 `limit` 参数。 +- **控制方式:** 该端点按返回行数计费,但没有已记录的 `limit` 参数。不要承诺调用方可通过 `limit` 降低费用;应把公开示例和上限视为一次被接受请求的成本暴露。 + + +### [Popular Pages](/api-reference/similarweb/get_similarweb-website-popular-pages) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `3 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(3 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 3 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [Website Subdomains](/api-reference/similarweb/get_similarweb-website-subdomains) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `2 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(2 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 2 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [Keyword Competitors](/api-reference/similarweb/get_similarweb-search-keyword-competitors) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `0.03 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(0.03 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 0.03 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [Website Keywords](/api-reference/similarweb/get_similarweb-search-website-keywords) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `0.1 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(0.1 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 0.1 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [SERP Players - Clicks over time](/api-reference/similarweb/get_similarweb-search-serp-players-timeseries) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `0.02 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(0.02 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 0.02 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [SERP Players - Aggregated](/api-reference/similarweb/get_similarweb-search-serp-players-aggregated) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `0.07 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(0.07 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 0.07 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [Landing Pages](/api-reference/similarweb/get_similarweb-search-landing-pages) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `0.1 / row (max 20 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(0.1 x rows); rows capped at 20`。 +- **费用驱动因素:** `limit`:按返回行数以 0.1 credit/行累积计费,最多计 20 行。 +- **当前公开示例:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` +- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 + + +### [Website Top Geographies](/api-reference/similarweb/get_similarweb-website-top-geographies) + +- **计费方式:** 按返回行数 credit 计费。 +- **Credit 费率:** `3 / row (max 10 rows)`,每 credit `$0.10`。 +- **公式:** `credits = ceil(3 x rows); rows capped at 10`。 +- **费用驱动因素:** `limit`:按返回行数以 3 credit/行累积计费,最多计 10 行。 +- **公开最大成本暴露示例:** `10 rows = 30 credits ($3.00)`。源数据中的 `limit=...` 仅用于说明计量,不是该端点接受的 `limit` 参数。 +- **控制方式:** 该端点按返回行数计费,但没有已记录的 `limit` 参数。不要承诺调用方可通过 `limit` 降低费用;应把公开示例和上限视为一次被接受请求的成本暴露。 + +## 固定每请求计费 + + +### [Demographics](/api-reference/similarweb/get_similarweb-website-demographics) + +- **计费方式:** 固定每请求 credit 计费。 +- **Credit 费率:** `8 credits (fixed)`,每 credit `$0.10`。 +- **公式:** `credits = 8 (fixed per request)`。 +- **费用驱动因素:** `(none)`:每次请求固定 credit 费用。 +- **当前公开示例:** `1 request = 8 credits ($0.80)` +- **控制方式:** 该类请求的公开 credit 费用是固定的。 + + +### [Website Technologies](/api-reference/similarweb/get_similarweb-website-technologies) + +- **计费方式:** 固定每请求 credit 计费。 +- **Credit 费率:** `10 credits (fixed)`,每 credit `$0.10`。 +- **公式:** `credits = 10 (fixed per request)`。 +- **费用驱动因素:** `(none)`:每次请求固定 credit 费用。 +- **当前公开示例:** `1 request = 10 credits ($1.00)` +- **控制方式:** 该类请求的公开 credit 费用是固定的。 From 397e99b0dd3f04d07f0b61c9d3f4c007744b5da6 Mon Sep 17 00:00:00 2001 From: idan Date: Tue, 1 Sep 2026 16:13:24 +0800 Subject: [PATCH 2/8] ci: scope Mintlify validation to SimilarWeb pricing docs --- .../workflows/validate-similarweb-pricing.yml | 3 +- scripts/validate_similarweb_mintlify.py | 96 +++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 scripts/validate_similarweb_mintlify.py diff --git a/.github/workflows/validate-similarweb-pricing.yml b/.github/workflows/validate-similarweb-pricing.yml index dffba9d9..c75b367f 100644 --- a/.github/workflows/validate-similarweb-pricing.yml +++ b/.github/workflows/validate-similarweb-pricing.yml @@ -19,6 +19,7 @@ on: - "scripts/check_similarweb_pricing.py" - "scripts/consolidate_openapi.py" - "scripts/generate_similarweb_pricing_docs.py" + - "scripts/validate_similarweb_mintlify.py" workflow_dispatch: permissions: @@ -59,7 +60,7 @@ jobs: run: python scripts/check_similarweb_pricing.py --generated /tmp/openapi.yaml - name: Validate generated docs and OpenAPI with Mintlify - run: npx --yes mint@4.2.854 validate + run: python scripts/validate_similarweb_mintlify.py - name: Check patch whitespace run: git diff --check "origin/${{ github.base_ref }}...HEAD" diff --git a/scripts/validate_similarweb_mintlify.py b/scripts/validate_similarweb_mintlify.py new file mode 100644 index 00000000..33126aa8 --- /dev/null +++ b/scripts/validate_similarweb_mintlify.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +"""Validate the generated SimilarWeb documentation in a minimal Mintlify site. + +The full repository currently contains unrelated historical MDX parse warnings. +This script copies only the generated pricing guides, all SimilarWeb endpoint +pages, and their OpenAPI source into a temporary Mintlify project, then runs the +same strict ``mint validate`` command used in CI. It validates the surfaces this +pricing contract owns without mutating or suppressing diagnostics in the source +repository. +""" + +from __future__ import annotations + +import argparse +import json +import shutil +import subprocess +import tempfile +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[1] +GUIDE_PATHS = ( + ROOT / "guides" / "pricing" / "similarweb.mdx", + ROOT / "zh" / "guides" / "pricing" / "similarweb.mdx", +) +API_REFERENCE_DIR = ROOT / "api-reference" / "similarweb" +OPENAPI_PATH = ROOT / "openapi" / "similarweb.json" + + +def copy_into_fixture(source: Path, fixture_root: Path) -> None: + target = fixture_root / source.relative_to(ROOT) + target.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(source, target) + + +def build_fixture(fixture_root: Path) -> int: + endpoint_pages = sorted(API_REFERENCE_DIR.glob("*.mdx")) + if not endpoint_pages: + raise SystemExit("Mintlify fixture has no SimilarWeb endpoint pages") + + for path in (*GUIDE_PATHS, *endpoint_pages, OPENAPI_PATH): + if not path.exists(): + raise SystemExit(f"Mintlify fixture input is missing: {path.relative_to(ROOT)}") + copy_into_fixture(path, fixture_root) + + pages = [ + "guides/pricing/similarweb", + "zh/guides/pricing/similarweb", + *(path.relative_to(ROOT).with_suffix("").as_posix() for path in endpoint_pages), + ] + config = { + "name": "SimilarWeb pricing validation", + "theme": "mint", + "colors": {"primary": "#F76B15"}, + "navigation": { + "groups": [ + { + "group": "SimilarWeb pricing", + "pages": pages, + } + ] + }, + } + (fixture_root / "docs.json").write_text( + json.dumps(config, indent=2) + "\n", + encoding="utf-8", + ) + return len(endpoint_pages) + + +def main() -> None: + parser = argparse.ArgumentParser() + parser.add_argument( + "--prepare-only", + action="store_true", + help="validate the fixture inputs and configuration without running Mintlify", + ) + args = parser.parse_args() + + with tempfile.TemporaryDirectory(prefix="aisa-similarweb-mintlify-") as directory: + fixture_root = Path(directory) + endpoint_count = build_fixture(fixture_root) + if args.prepare_only: + print(f"Mintlify fixture prepared: {endpoint_count} SimilarWeb endpoint pages") + return + subprocess.run( + ["npx", "--yes", "mint@4.2.854", "validate"], + cwd=fixture_root, + check=True, + ) + print(f"Mintlify validated SimilarWeb fixture: {endpoint_count} endpoint pages") + + +if __name__ == "__main__": + main() From 7cb61314fe26115e55673bbcd25af9fde24e74c7 Mon Sep 17 00:00:00 2001 From: idan Date: Wed, 2 Sep 2026 01:42:36 +0800 Subject: [PATCH 3/8] docs(similarweb): require explicit approval before data calls --- .../workflows/validate-similarweb-pricing.yml | 2 ++ agent-quickstart.mdx | 32 +++++++++++++++++++ guides/pricing/similarweb.mdx | 2 +- llms.txt | 6 +++- scripts/check_similarweb_pricing.py | 13 ++++++++ scripts/generate_similarweb_pricing_docs.py | 4 +-- scripts/validate_similarweb_mintlify.py | 18 +++++++---- zh/agent-quickstart.mdx | 27 ++++++++++++++++ zh/guides/pricing/similarweb.mdx | 2 +- 9 files changed, 95 insertions(+), 11 deletions(-) diff --git a/.github/workflows/validate-similarweb-pricing.yml b/.github/workflows/validate-similarweb-pricing.yml index c75b367f..12ee0842 100644 --- a/.github/workflows/validate-similarweb-pricing.yml +++ b/.github/workflows/validate-similarweb-pricing.yml @@ -7,6 +7,8 @@ on: - ".github/workflows/sync-openapi.yml" - "docs.json" - "llms.txt" + - "agent-quickstart.mdx" + - "zh/agent-quickstart.mdx" - "openapi/**" - "api-reference/similarweb/**" - "zh/api-reference/similarweb/**" diff --git a/agent-quickstart.mdx b/agent-quickstart.mdx index 0ff4ce85..f4aef1a0 100644 --- a/agent-quickstart.mdx +++ b/agent-quickstart.mdx @@ -10,6 +10,38 @@ This page helps locate the relevant technical source. Reading it is not independ Goal: get the agent to the smallest verifiable next step without loading broad documentation indexes. +## IMPORTANT: SimilarWeb approval-first contract + +This contract applies to every SimilarWeb **data** endpoint, whether it is invoked directly under `/apis/v1/similarweb/...` or through a SimilarWeb MCP data tool. It is a safety boundary, not a price discovery workflow. + +```xml + + + Read the matching endpoint documentation, its x-aisa-pricing metadata, and + SimilarWeb Pricing & Cost Control. You may inspect docs, /v1/models, and + MCP discovery before approval. These are discovery surfaces only. + + + Identify the exact endpoint and request scope (such as domain, dates, + metrics, limit, and body). Use the matching x-aisa-pricing formula and its + documented maximum exposure to explain the maximum cost in USD. Present + that exact scope, formula, and maximum cost to the user, then obtain the + user's explicit approval for that scope and cap. + + + Do not call a SimilarWeb data endpoint to discover price, "probe", "test", + or "just check". Do not invent or call a quote API. A catalog display + value, including zero, is not a request-specific quote. + + + Execute only the approved request. If the endpoint, scope, or maximum cost + changes, present the new details and obtain a new explicit approval. + + +``` + +The matching endpoint's [`x-aisa-pricing`](https://aisa.one/openapi.yaml) metadata and [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb) are the published pricing source of truth. They provide the formula and documented exposure; they do not create a quote API or authorize a data call. + ## Minimal setup facts AIsa provides two endpoint families: diff --git a/guides/pricing/similarweb.mdx b/guides/pricing/similarweb.mdx index 1668785f..83dd69d2 100644 --- a/guides/pricing/similarweb.mdx +++ b/guides/pricing/similarweb.mdx @@ -8,7 +8,7 @@ excerpt: >- SimilarWeb is a paid data API with credit-based pricing. Its catalog display value is not always a fixed, request-specific quote. - **IMPORTANT:** Before a paid SimilarWeb request, read the matching endpoint disclosure below, state the cost driver and documented exposure, and use the smallest scope that answers the task. For request-dimension pricing, obtain a budget decision before execution. + **IMPORTANT — approval-first:** A SimilarWeb data endpoint is not price discovery. Before any data request, use the matching `x-aisa-pricing` disclosure to state the exact scope, formula, and documented maximum exposure; then obtain explicit user approval for that scope and cap. Never send an unapproved probe, test, or "just check" request. Docs, `/v1/models`, and MCP discovery are allowed discovery surfaces. This page is generated from each endpoint's `x-aisa-pricing` object in the [machine-readable OpenAPI](https://aisa.one/openapi.yaml). It intentionally does not maintain a second hand-authored rate schedule. diff --git a/llms.txt b/llms.txt index 95565f03..99e5d307 100644 --- a/llms.txt +++ b/llms.txt @@ -14,6 +14,10 @@ Use this index to choose the smallest relevant documentation set. For product di - [Errors](https://aisa.one/docs/api-reference/errors): error formats and handling. - [Rate Limits](https://aisa.one/docs/api-reference/rate-limits): limits and relevant headers. + +For any SimilarWeb data endpoint, first read the matching `x-aisa-pricing` disclosure and Pricing & Cost Control page. You may read docs, `/v1/models`, and MCP discovery before approval, but a SimilarWeb data endpoint is not price discovery. Before a data call, present the exact scope, pricing formula, and documented maximum USD exposure; obtain the user's explicit approval for that scope and cap. Never send an unapproved probe, test, or "just check" request, and do not invent a quote API. If the scope or maximum changes, request new approval. + + ## Navigate by Goal - [Capabilities by Goal](https://aisa.one/docs/by-goal): choose models, Skills, and APIs from the outcome an agent needs. @@ -70,4 +74,4 @@ Use this index to choose the smallest relevant documentation set. For product di - Treat search results as discovery, fetched pages as evidence, and generated text as synthesis. - Separate read operations from writes and payments; verify authorization before side effects. - Check live availability, status, pricing, and authentication before relying on a capability. -- For SimilarWeb, load the matching endpoint and [SimilarWeb Pricing & Cost Control](https://aisa.one/docs/guides/pricing/similarweb); do not treat a catalog display value as a request-specific quote. +- For SimilarWeb, follow the approval-first contract above: load the matching endpoint and [SimilarWeb Pricing & Cost Control](https://aisa.one/docs/guides/pricing/similarweb), state the formula and documented maximum exposure, then request explicit approval before the data call. Do not treat a catalog display value as a request-specific quote. diff --git a/scripts/check_similarweb_pricing.py b/scripts/check_similarweb_pricing.py index 510a1f29..8f09ce2f 100644 --- a/scripts/check_similarweb_pricing.py +++ b/scripts/check_similarweb_pricing.py @@ -27,6 +27,8 @@ LLMS_PATH = ROOT / "llms.txt" NAV_PATH = ROOT / "docs.json" +AGENT_QUICKSTART_PATH = ROOT / "agent-quickstart.mdx" +ZH_AGENT_QUICKSTART_PATH = ROOT / "zh" / "agent-quickstart.mdx" PRICING_OVERVIEW_PATH = ROOT / "guides" / "pricing.mdx" PER_CALL_PATH = ROOT / "guides" / "pricing" / "per-call-api-pricing.mdx" ZH_PRICING_OVERVIEW_PATH = ROOT / "zh" / "guides" / "pricing.mdx" @@ -82,6 +84,17 @@ def check_checked_in_surfaces(source: dict[str, Any]) -> None: llms = LLMS_PATH.read_text(encoding="utf-8") if "guides/pricing/similarweb" not in llms or "SimilarWeb Pricing & Cost Control" not in llms: fail("llms.txt does not route agents to SimilarWeb pricing guidance") + for marker in ("", "explicit approval", "price discovery", "x-aisa-pricing", "/v1/models", "MCP discovery"): + if marker not in llms: + fail(f"llms.txt lacks SimilarWeb approval-first marker: {marker}") + for path, markers in ( + (AGENT_QUICKSTART_PATH, ("", "explicit approval", "price discovery", "x-aisa-pricing", "/v1/models", "MCP discovery")), + (ZH_AGENT_QUICKSTART_PATH, ("", "明确批准", "价格发现", "x-aisa-pricing", "/v1/models", "MCP discovery")), + ): + content = path.read_text(encoding="utf-8") + for marker in markers: + if marker not in content: + fail(f"{path.relative_to(ROOT)} lacks SimilarWeb approval-first marker: {marker}") similar_sites = next(operation for operation in operations if operation.operation_id == "get_similarweb_similar_sites") endpoint_url = f"https://aisa.one/docs{similar_sites.endpoint_url}" if endpoint_url not in llms: diff --git a/scripts/generate_similarweb_pricing_docs.py b/scripts/generate_similarweb_pricing_docs.py index d3e71f2c..a8261cda 100644 --- a/scripts/generate_similarweb_pricing_docs.py +++ b/scripts/generate_similarweb_pricing_docs.py @@ -491,7 +491,7 @@ def render_guide_en(operations: list[Operation]) -> str: "SimilarWeb is a paid data API with credit-based pricing. Its catalog display value is not always a fixed, request-specific quote.", "", "", - " **IMPORTANT:** Before a paid SimilarWeb request, read the matching endpoint disclosure below, state the cost driver and documented exposure, and use the smallest scope that answers the task. For request-dimension pricing, obtain a budget decision before execution.", + " **IMPORTANT — approval-first:** A SimilarWeb data endpoint is not price discovery. Before any data request, use the matching `x-aisa-pricing` disclosure to state the exact scope, formula, and documented maximum exposure; then obtain explicit user approval for that scope and cap. Never send an unapproved probe, test, or \"just check\" request. Docs, `/v1/models`, and MCP discovery are allowed discovery surfaces.", "", "", "This page is generated from each endpoint's `x-aisa-pricing` object in the [machine-readable OpenAPI](https://aisa.one/openapi.yaml). It intentionally does not maintain a second hand-authored rate schedule.", @@ -531,7 +531,7 @@ def render_guide_zh(operations: list[Operation]) -> str: "SimilarWeb 是付费数据 API,采用 credit 计费。目录展示值并不总是某次请求的固定、精确报价。", "", "", - " **重要(IMPORTANT):** 发起付费 SimilarWeb 请求前,请阅读下面对应端点的价格说明,向用户说明费用驱动因素和已记录的成本暴露,并选择足以回答问题的最小范围。对于按请求维度计费的端点,执行前必须取得预算确认。", + " **重要(IMPORTANT,先批准后执行):** SimilarWeb 数据 endpoint 不是价格发现入口。发起任何数据请求前,请使用匹配的 `x-aisa-pricing` 说明明确 scope、公式和已记录的最大成本暴露,再取得用户对该 scope 与上限的明确批准。绝不能发送未经批准的 probe、test 或“先探一下”请求;docs、`/v1/models` 和 MCP discovery 可以作为发现入口。", "", "", "本页从 [机器可读 OpenAPI](https://aisa.one/openapi.yaml) 中每个端点的 `x-aisa-pricing` 对象自动生成,故意不维护第二份手写费率表。", diff --git a/scripts/validate_similarweb_mintlify.py b/scripts/validate_similarweb_mintlify.py index 33126aa8..0905b94a 100644 --- a/scripts/validate_similarweb_mintlify.py +++ b/scripts/validate_similarweb_mintlify.py @@ -2,11 +2,11 @@ """Validate the generated SimilarWeb documentation in a minimal Mintlify site. The full repository currently contains unrelated historical MDX parse warnings. -This script copies only the generated pricing guides, all SimilarWeb endpoint -pages, and their OpenAPI source into a temporary Mintlify project, then runs the -same strict ``mint validate`` command used in CI. It validates the surfaces this -pricing contract owns without mutating or suppressing diagnostics in the source -repository. +This script copies only the generated pricing guides, agent-quickstart policy +pages, all SimilarWeb endpoint pages, and their OpenAPI source into a temporary +Mintlify project, then runs the same strict ``mint validate`` command used in +CI. It validates the surfaces this pricing contract owns without mutating or +suppressing diagnostics in the source repository. """ from __future__ import annotations @@ -24,6 +24,10 @@ ROOT / "guides" / "pricing" / "similarweb.mdx", ROOT / "zh" / "guides" / "pricing" / "similarweb.mdx", ) +POLICY_PATHS = ( + ROOT / "agent-quickstart.mdx", + ROOT / "zh" / "agent-quickstart.mdx", +) API_REFERENCE_DIR = ROOT / "api-reference" / "similarweb" OPENAPI_PATH = ROOT / "openapi" / "similarweb.json" @@ -39,12 +43,14 @@ def build_fixture(fixture_root: Path) -> int: if not endpoint_pages: raise SystemExit("Mintlify fixture has no SimilarWeb endpoint pages") - for path in (*GUIDE_PATHS, *endpoint_pages, OPENAPI_PATH): + for path in (*GUIDE_PATHS, *POLICY_PATHS, *endpoint_pages, OPENAPI_PATH): if not path.exists(): raise SystemExit(f"Mintlify fixture input is missing: {path.relative_to(ROOT)}") copy_into_fixture(path, fixture_root) pages = [ + "agent-quickstart", + "zh/agent-quickstart", "guides/pricing/similarweb", "zh/guides/pricing/similarweb", *(path.relative_to(ROOT).with_suffix("").as_posix() for path in endpoint_pages), diff --git a/zh/agent-quickstart.mdx b/zh/agent-quickstart.mdx index a3270e1f..200d357d 100644 --- a/zh/agent-quickstart.mdx +++ b/zh/agent-quickstart.mdx @@ -10,6 +10,33 @@ description: >- 目标:让 Agent 走到**最小且可验证**的下一步,而不是一次性加载完整文档索引。 +## 重要:SimilarWeb 先批准后执行合同 + +该合同适用于每一个 SimilarWeb **数据** endpoint,无论它是直接通过 `/apis/v1/similarweb/...` 调用,还是通过 SimilarWeb MCP 数据工具调用。这是一条安全边界,不是价格发现流程。 + +```xml + + + 可以先阅读匹配的 endpoint 文档、x-aisa-pricing 元数据和 SimilarWeb 价格与成本控制页; + 也可以查看 docs、/v1/models 和 MCP discovery。这些都只是发现入口。 + + + 明确本次 endpoint 和请求范围(如 domain、日期、metrics、limit 和 body)。使用匹配的 + x-aisa-pricing 公式及其已记录的最大成本暴露,说明最高 USD 费用;向用户展示这一精确 + scope、公式和最高费用后,必须取得用户对该 scope 与上限的明确批准。 + + + 不得为了价格发现、"probe"、"test" 或“先探一下”而调用 SimilarWeb 数据 endpoint。 + 不得编造或调用报价 API。目录展示值(包括 0)不是某次请求的精确报价。 + + + 只能执行已批准的请求;如果 endpoint、scope 或最高费用变化,必须重新展示细节并取得新的明确批准。 + + +``` + +匹配 endpoint 的 [`x-aisa-pricing`](https://aisa.one/openapi.yaml) 元数据和 [SimilarWeb 价格与成本控制](/zh/guides/pricing/similarweb) 是公开计价的唯一来源;它们提供公式和已记录的成本暴露,不会形成报价 API,也不构成数据调用授权。 + ## 最小设置事实 AIsa 提供两类端点: diff --git a/zh/guides/pricing/similarweb.mdx b/zh/guides/pricing/similarweb.mdx index aff7b354..dfd6dde3 100644 --- a/zh/guides/pricing/similarweb.mdx +++ b/zh/guides/pricing/similarweb.mdx @@ -8,7 +8,7 @@ excerpt: >- SimilarWeb 是付费数据 API,采用 credit 计费。目录展示值并不总是某次请求的固定、精确报价。 - **重要(IMPORTANT):** 发起付费 SimilarWeb 请求前,请阅读下面对应端点的价格说明,向用户说明费用驱动因素和已记录的成本暴露,并选择足以回答问题的最小范围。对于按请求维度计费的端点,执行前必须取得预算确认。 + **重要(IMPORTANT,先批准后执行):** SimilarWeb 数据 endpoint 不是价格发现入口。发起任何数据请求前,请使用匹配的 `x-aisa-pricing` 说明明确 scope、公式和已记录的最大成本暴露,再取得用户对该 scope 与上限的明确批准。绝不能发送未经批准的 probe、test 或“先探一下”请求;docs、`/v1/models` 和 MCP discovery 可以作为发现入口。 本页从 [机器可读 OpenAPI](https://aisa.one/openapi.yaml) 中每个端点的 `x-aisa-pricing` 对象自动生成,故意不维护第二份手写费率表。 From 7c4fad48b9fb6dd861e80fa0ea6bbbe1f59fffcd Mon Sep 17 00:00:00 2001 From: idan Date: Wed, 2 Sep 2026 11:37:07 +0800 Subject: [PATCH 4/8] fix(docs): fail closed on unbounded SimilarWeb pricing --- agent-quickstart.mdx | 3 + evaluate/pricing.mdx | 3 +- guides/pricing/similarweb.mdx | 8 +- llms.txt | 2 +- openapi/similarweb.json | 533 +++++++++++++++++++- scripts/check_similarweb_pricing.py | 26 +- scripts/generate_similarweb_pricing_docs.py | 150 ++++-- zh/agent-quickstart.mdx | 2 + zh/evaluate/pricing.mdx | 3 +- zh/guides/pricing/similarweb.mdx | 8 +- 10 files changed, 672 insertions(+), 66 deletions(-) diff --git a/agent-quickstart.mdx b/agent-quickstart.mdx index f4aef1a0..7b14dcfb 100644 --- a/agent-quickstart.mdx +++ b/agent-quickstart.mdx @@ -27,6 +27,9 @@ This contract applies to every SimilarWeb **data** endpoint, whether it is invok documented maximum exposure to explain the maximum cost in USD. Present that exact scope, formula, and maximum cost to the user, then obtain the user's explicit approval for that scope and cap. + If provider-controlled dimensions have no documented upper bound, do not + treat a minimum/example as a cap and do not execute that endpoint under + this approval-first contract. Do not call a SimilarWeb data endpoint to discover price, "probe", "test", diff --git a/evaluate/pricing.mdx b/evaluate/pricing.mdx index 535d1523..1f81b094 100644 --- a/evaluate/pricing.mdx +++ b/evaluate/pricing.mdx @@ -58,9 +58,10 @@ A direct provider can be the simpler option for a stable, single-provider worklo ## Verify before production +- For SimilarWeb, do not run a SimilarWeb request to discover price or validate setup. First present the exact scope, formula, and documented maximum, then obtain explicit approval. If there is no documented upper bound, do not execute that endpoint under the approval-first contract. - Confirm the exact model ID or endpoint. - Check current price units. -- Run a small representative request. +- For APIs other than SimilarWeb, run a small representative request. - Inspect the usage record. - Measure the complete workflow, not only one call. - Add budget alerts before scaling traffic. diff --git a/guides/pricing/similarweb.mdx b/guides/pricing/similarweb.mdx index 83dd69d2..b69464ca 100644 --- a/guides/pricing/similarweb.mdx +++ b/guides/pricing/similarweb.mdx @@ -78,8 +78,8 @@ Do not treat a catalog `pricing.normal` value of `0` as a free SimilarWeb reques - **Credit rate:** `1 credit / (metric x month)` at `$0.10` per credit. - **Formula:** `credits = 1 x metrics x periods`. - **Cost drivers:** `metrics`: number of metrics requested; `periods`: number of months in the date window. -- **Provider-controlled schedule example:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters. -- **Control:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. Treat the published example as the documented exposure and obtain a budget decision before execution. +- **Provider-controlled lower-bound example:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters. +- **Control:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. ### [Website Traffic Trend](/api-reference/similarweb/get_similarweb-website-traffic-trend) @@ -88,8 +88,8 @@ Do not treat a catalog `pricing.normal` value of `0` as a free SimilarWeb reques - **Credit rate:** `1 credit / (metric x month)` at `$0.10` per credit. - **Formula:** `credits = 1 x metrics x periods`. - **Cost drivers:** `metrics`: number of metrics requested; `periods`: number of months in the date window. -- **Provider-controlled schedule example:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters. -- **Control:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. Treat the published example as the documented exposure and obtain a budget decision before execution. +- **Provider-controlled lower-bound example:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters. +- **Control:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. ## Returned-row pricing diff --git a/llms.txt b/llms.txt index 99e5d307..670f2b06 100644 --- a/llms.txt +++ b/llms.txt @@ -15,7 +15,7 @@ Use this index to choose the smallest relevant documentation set. For product di - [Rate Limits](https://aisa.one/docs/api-reference/rate-limits): limits and relevant headers. -For any SimilarWeb data endpoint, first read the matching `x-aisa-pricing` disclosure and Pricing & Cost Control page. You may read docs, `/v1/models`, and MCP discovery before approval, but a SimilarWeb data endpoint is not price discovery. Before a data call, present the exact scope, pricing formula, and documented maximum USD exposure; obtain the user's explicit approval for that scope and cap. Never send an unapproved probe, test, or "just check" request, and do not invent a quote API. If the scope or maximum changes, request new approval. +For any SimilarWeb data endpoint, first read the matching `x-aisa-pricing` disclosure and Pricing & Cost Control page. You may read docs, `/v1/models`, and MCP discovery before approval, but a SimilarWeb data endpoint is not price discovery. Before a data call, present the exact scope, pricing formula, and documented maximum USD exposure; obtain the user's explicit approval for that scope and cap. If provider-controlled dimensions have no documented upper bound, a minimum/example is not a cap and the endpoint must not execute under this approval-first contract. Never send an unapproved probe, test, or "just check" request, and do not invent a quote API. If the scope or maximum changes, request new approval. ## Navigate by Goal diff --git a/openapi/similarweb.json b/openapi/similarweb.json index 03e21dd3..55d4df4a 100644 --- a/openapi/similarweb.json +++ b/openapi/similarweb.json @@ -228,6 +228,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -395,6 +418,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -556,6 +602,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -682,6 +751,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -857,6 +949,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -1054,6 +1169,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -1252,6 +1390,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -1455,6 +1616,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -1650,6 +1834,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -1837,6 +2044,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -2044,6 +2274,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -2182,6 +2435,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -2388,6 +2664,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -2586,6 +2885,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -2774,6 +3096,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -2969,6 +3314,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -3209,6 +3577,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -3370,6 +3761,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -3561,6 +3975,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -3785,6 +4222,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -3812,7 +4272,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Website Traffic Snapshot", - "description": "Latest-month traffic snapshot for a domain: visits plus core engagement metrics (average visit duration, bounce rate, pages per visit) in a single object. The most recent available month is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled schedule example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. Treat the published example as the documented exposure and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-traffic-snapshot) before a paid request.\n\n", + "description": "Latest-month traffic snapshot for a domain: visits plus core engagement metrics (average visit duration, bounce rate, pages per visit) in a single object. The most recent available month is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled lower-bound example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-traffic-snapshot) before a paid request.\n\n", "operationId": "get_similarweb_website_traffic_snapshot", "parameters": [ { @@ -3925,6 +4385,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -3952,7 +4435,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Website Traffic Trend", - "description": "Monthly traffic time series for a domain over the recent available window (data.points, one entry per month). The window is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled schedule example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. Treat the published example as the documented exposure and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-traffic-trend) before a paid request.\n\n", + "description": "Monthly traffic time series for a domain over the recent available window (data.points, one entry per month). The window is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled lower-bound example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-traffic-trend) before a paid request.\n\n", "operationId": "get_similarweb_website_traffic_trend", "parameters": [ { @@ -4104,6 +4587,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } @@ -4291,6 +4797,29 @@ } } } + }, + "headers": { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": { + "type": "number", + "format": "float" + } + } } } } diff --git a/scripts/check_similarweb_pricing.py b/scripts/check_similarweb_pricing.py index 8f09ce2f..843a12ec 100644 --- a/scripts/check_similarweb_pricing.py +++ b/scripts/check_similarweb_pricing.py @@ -14,6 +14,7 @@ EXPECTED_OPERATION_IDS, GUIDE_PATH, ROOT, + SETTLEMENT_RESPONSE_HEADERS, SOURCE_PATH, ZH_GUIDE_PATH, check_outputs, @@ -33,6 +34,8 @@ PER_CALL_PATH = ROOT / "guides" / "pricing" / "per-call-api-pricing.mdx" ZH_PRICING_OVERVIEW_PATH = ROOT / "zh" / "guides" / "pricing.mdx" ZH_PER_CALL_PATH = ROOT / "zh" / "guides" / "pricing" / "per-call-api-pricing.mdx" +EVALUATE_PRICING_PATH = ROOT / "evaluate" / "pricing.mdx" +ZH_EVALUATE_PRICING_PATH = ROOT / "zh" / "evaluate" / "pricing.mdx" def fail(message: str) -> None: @@ -70,7 +73,11 @@ def check_checked_in_surfaces(source: dict[str, Any]) -> None: if f'' not in content: fail(f"{guide.relative_to(ROOT)} has no anchor for {operation.operation_id}") - description = source["paths"][operation.path]["get"]["description"] + source_operation = source["paths"][operation.path][operation.method] + description = source_operation["description"] + response = source_operation.get("responses", {}).get("200") + if not isinstance(response, dict) or response.get("headers") != SETTLEMENT_RESPONSE_HEADERS: + fail(f"{operation.operation_id} lacks the generated settlement response headers") uncontrolled = provider_controlled_drivers(operation) if category(operation) == "rows" and uncontrolled: if "does not accept `limit`" not in description: @@ -80,6 +87,8 @@ def check_checked_in_surfaces(source: dict[str, Any]) -> None: if category(operation) == "dimensions" and uncontrolled and not operation.parameter_names.intersection({"metrics", "start_date", "end_date"}): if "provider-controlled dimensions" not in description: fail(f"{operation.operation_id} does not disclose provider-controlled pricing dimensions") + if "documentation does not publish an upper bound" not in description or "not an approval cap" not in description: + fail(f"{operation.operation_id} presents a provider-controlled lower bound as an approval cap") llms = LLMS_PATH.read_text(encoding="utf-8") if "guides/pricing/similarweb" not in llms or "SimilarWeb Pricing & Cost Control" not in llms: @@ -116,6 +125,15 @@ def check_checked_in_surfaces(source: dict[str, Any]) -> None: if "similarweb" not in path.read_text(encoding="utf-8").lower(): fail(f"{path.relative_to(ROOT)} does not link to SimilarWeb pricing guidance") + for path, markers in ( + (EVALUATE_PRICING_PATH, ("do not run a SimilarWeb request to discover price", "explicit approval")), + (ZH_EVALUATE_PRICING_PATH, ("不得通过 SimilarWeb 请求发现价格", "明确批准")), + ): + content = path.read_text(encoding="utf-8") + for marker in markers: + if marker not in content: + fail(f"{path.relative_to(ROOT)} lacks the SimilarWeb no-probe exception: {marker}") + def check_consolidated_openapi(source: dict[str, Any], generated_path: Path) -> None: with generated_path.open(encoding="utf-8") as stream: @@ -125,9 +143,13 @@ def check_consolidated_openapi(source: dict[str, Any], generated_path: Path) -> for operation in collect_operations(source): expected = operation.pricing - actual = generated["paths"].get(operation.path, {}).get("get", {}).get("x-aisa-pricing") + generated_operation = generated["paths"].get(operation.path, {}).get(operation.method, {}) + actual = generated_operation.get("x-aisa-pricing") if actual != expected: fail(f"generated OpenAPI did not preserve x-aisa-pricing for {operation.path}") + response = generated_operation.get("responses", {}).get("200") + if not isinstance(response, dict) or response.get("headers") != SETTLEMENT_RESPONSE_HEADERS: + fail(f"generated OpenAPI did not preserve settlement headers for {operation.path}") def main() -> None: diff --git a/scripts/generate_similarweb_pricing_docs.py b/scripts/generate_similarweb_pricing_docs.py index a8261cda..08ecba81 100644 --- a/scripts/generate_similarweb_pricing_docs.py +++ b/scripts/generate_similarweb_pricing_docs.py @@ -15,6 +15,7 @@ import json import re from dataclasses import dataclass +from decimal import Decimal, InvalidOperation from pathlib import Path from typing import Any @@ -60,9 +61,25 @@ re.DOTALL, ) OPENAPI_REFERENCE_PATTERN = re.compile( - r'^openapi:\s+"openapi/similarweb\.json GET (?P[^"]+)"$', + r'^openapi:\s+"openapi/similarweb\.json (?P[A-Z]+) (?P[^"]+)"$', re.MULTILINE, ) +HTTP_METHODS = frozenset({"get", "put", "post", "delete", "options", "head", "patch", "trace"}) +SETTLEMENT_RESPONSE_HEADERS: dict[str, dict[str, Any]] = { + "X-AISA-Estimated-Credits": { + "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", + "schema": {"type": "number", "format": "float"}, + }, + "X-AISA-Accounted-Credits": { + "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", + "schema": {"type": "number", "format": "float"}, + }, + "X-AISA-Price-USD": { + "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", + "schema": {"type": "number", "format": "float"}, + }, +} +CREDIT_EXAMPLE_RE = re.compile(r"(?P\d+(?:\.\d+)?) credits? \(\$(?P\d+(?:\.\d+)?)\)") @dataclass(frozen=True) @@ -70,6 +87,7 @@ class Operation: """A SimilarWeb operation together with its #92 pricing contract.""" path: str + method: str operation_id: str endpoint_slug: str summary: str @@ -78,7 +96,8 @@ class Operation: @property def anchor(self) -> str: - return self.path.rsplit("/", 1)[-1] + endpoint = self.path.rsplit("/", 1)[-1] + return endpoint if self.method == "get" else f"{self.method}-{endpoint}" @property def endpoint_url(self) -> str: @@ -131,19 +150,37 @@ def validate_pricing(path: str, pricing: Any) -> dict[str, Any]: for field in ("param", "effect"): if not isinstance(driver.get(field), str) or not driver[field].strip(): fail(f"{path} has an invalid cost driver {field}") + examples = list(CREDIT_EXAMPLE_RE.finditer(pricing["example"])) + if not examples: + fail(f"{path} example has no parseable credits-to-USD amount") + credit_price = Decimal(str(pricing["credit_price_usd"])) + for match in examples: + try: + credits = Decimal(match.group("credits")) + documented_usd = Decimal(match.group("usd")) + except InvalidOperation as error: + raise AssertionError("credit example regex must only capture decimals") from error + expected_usd = credits * credit_price + if documented_usd != expected_usd: + fail( + f"{path} example has ${documented_usd} for {credits} credits; " + f"expected ${expected_usd} at ${credit_price} per credit" + ) return pricing -def api_reference_pages() -> dict[str, str]: - pages: dict[str, str] = {} +def api_reference_pages() -> dict[tuple[str, str], str]: + pages: dict[tuple[str, str], str] = {} for page in API_REFERENCE_DIR.glob("*.mdx"): match = OPENAPI_REFERENCE_PATTERN.search(page.read_text(encoding="utf-8")) if not match: continue path = match.group("path") - if path in pages: - fail(f"duplicate endpoint page for {path}") - pages[path] = page.stem + method = match.group("method").lower() + key = (path, method) + if key in pages: + fail(f"duplicate endpoint page for {method.upper()} {path}") + pages[key] = page.stem return pages @@ -158,44 +195,49 @@ def collect_operations(source: dict[str, Any]) -> list[Operation]: for path, item in paths.items(): if not isinstance(item, dict): continue - operation = item.get("get") - if not isinstance(operation, dict) or "x-aisa-pricing" not in operation: - continue - - operation_id = operation.get("operationId") - summary = operation.get("summary") - description = operation.get("description") - if not isinstance(operation_id, str) or not operation_id: - fail(f"{path} has no operationId") - if not isinstance(summary, str) or not summary: - fail(f"{path} has no summary") - if not isinstance(description, str) or not description: - fail(f"{path} has no description") - if operation_id in seen_ids: - fail(f"duplicate operationId {operation_id}") - seen_ids.add(operation_id) - endpoint_slug = reference_pages.get(path) - if not endpoint_slug: - fail(f"{path} has no API reference page") - - parameters = operation.get("parameters", []) - if not isinstance(parameters, list): - fail(f"{path} has invalid parameters") - parameter_names = frozenset( - parameter["name"] - for parameter in parameters - if isinstance(parameter, dict) and isinstance(parameter.get("name"), str) - ) - operations.append( - Operation( - path=path, - operation_id=operation_id, - endpoint_slug=endpoint_slug, - summary=summary, - pricing=validate_pricing(path, operation["x-aisa-pricing"]), - parameter_names=parameter_names, + for method, operation in item.items(): + if method not in HTTP_METHODS: + continue + if not isinstance(operation, dict): + fail(f"{method.upper()} {path} is not an operation object") + if "x-aisa-pricing" not in operation: + fail(f"{method.upper()} {path} has no x-aisa-pricing object") + + operation_id = operation.get("operationId") + summary = operation.get("summary") + description = operation.get("description") + if not isinstance(operation_id, str) or not operation_id: + fail(f"{method.upper()} {path} has no operationId") + if not isinstance(summary, str) or not summary: + fail(f"{method.upper()} {path} has no summary") + if not isinstance(description, str) or not description: + fail(f"{method.upper()} {path} has no description") + if operation_id in seen_ids: + fail(f"duplicate operationId {operation_id}") + seen_ids.add(operation_id) + endpoint_slug = reference_pages.get((path, method)) + if not endpoint_slug: + fail(f"{method.upper()} {path} has no API reference page") + + parameters = operation.get("parameters", []) + if not isinstance(parameters, list): + fail(f"{method.upper()} {path} has invalid parameters") + parameter_names = frozenset( + parameter["name"] + for parameter in parameters + if isinstance(parameter, dict) and isinstance(parameter.get("name"), str) + ) + operations.append( + Operation( + path=path, + method=method, + operation_id=operation_id, + endpoint_slug=endpoint_slug, + summary=summary, + pricing=validate_pricing(f"{method.upper()} {path}", operation["x-aisa-pricing"]), + parameter_names=parameter_names, + ) ) - ) found_ids = {operation.operation_id for operation in operations} missing = sorted(EXPECTED_OPERATION_IDS - found_ids) @@ -291,7 +333,7 @@ def display_example_en(operation: Operation) -> tuple[str, str]: if category(operation) == "dimensions" and uncontrolled: names = ", ".join(f"`{name}`" for name in uncontrolled) return ( - "Provider-controlled schedule example", + "Provider-controlled lower-bound example", f"`{raw_example.rstrip('.')}`. {names} are provider-controlled for this endpoint, not caller-selectable request parameters.", ) return "Current schedule example", f"`{raw_example}`" @@ -309,7 +351,7 @@ def display_example_zh(operation: Operation) -> tuple[str, str]: if category(operation) == "dimensions" and uncontrolled: names = "、".join(f"`{name}`" for name in uncontrolled) return ( - "Provider 控制的计价表示例", + "Provider 控制的最低示例", f"`{raw_example.rstrip('.')}`。对于该端点,{names} 由 provider 控制,不能由调用方作为请求参数选择。", ) return "当前公开示例", f"`{raw_example}`" @@ -332,7 +374,8 @@ def control_en(operation: Operation) -> str: names = ", ".join(f"`{name}`" for name in uncontrolled) return ( f"The formula includes provider-controlled dimensions ({names}) that are not accepted request parameters. " - "Treat the published example as the documented exposure and obtain a budget decision before execution." + "The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. " + "Do not execute this operation under the approval-first contract until a documented maximum is available." ) control_names = ", ".join( "the `start_date`/`end_date` range" if name == "periods" else f"`{name}`" @@ -362,7 +405,8 @@ def control_zh(operation: Operation) -> str: names = "、".join(f"`{name}`" for name in uncontrolled) return ( f"公式包含由 provider 控制且不能作为请求参数传入的维度({names})。" - "请把公开示例视为已记录的成本暴露,并在执行前取得预算确认。" + "文档没有公开上限,因此示例只是最低值,不能作为批准上限。" + "在有已记录的最大上限前,不得按先批准后执行合同调用该端点。" ) control_names = "、".join( "`start_date`/`end_date` 日期范围" if name == "periods" else f"`{name}`" @@ -420,15 +464,19 @@ def strip_generated_disclosure(description: str) -> str: def render_source(source: dict[str, Any], operations: list[Operation]) -> str: rendered = copy.deepcopy(source) for operation in operations: - target = rendered["paths"][operation.path]["get"] + target = rendered["paths"][operation.path][operation.method] base_description = strip_generated_disclosure(target["description"]) target["description"] = f"{base_description}\n\n{generated_disclosure(operation)}\n" + responses = target.get("responses") + if not isinstance(responses, dict) or not isinstance(responses.get("200"), dict): + fail(f"{operation.method.upper()} {operation.path} has no 200 response for settlement headers") + responses["200"]["headers"] = copy.deepcopy(SETTLEMENT_RESPONSE_HEADERS) source_metadata = { - operation.path: operation.pricing for operation in collect_operations(source) + (operation.path, operation.method): operation.pricing for operation in collect_operations(source) } rendered_metadata = { - operation.path: rendered["paths"][operation.path]["get"]["x-aisa-pricing"] + (operation.path, operation.method): rendered["paths"][operation.path][operation.method]["x-aisa-pricing"] for operation in operations } if rendered_metadata != source_metadata: diff --git a/zh/agent-quickstart.mdx b/zh/agent-quickstart.mdx index 200d357d..eab1d5d1 100644 --- a/zh/agent-quickstart.mdx +++ b/zh/agent-quickstart.mdx @@ -24,6 +24,8 @@ description: >- 明确本次 endpoint 和请求范围(如 domain、日期、metrics、limit 和 body)。使用匹配的 x-aisa-pricing 公式及其已记录的最大成本暴露,说明最高 USD 费用;向用户展示这一精确 scope、公式和最高费用后,必须取得用户对该 scope 与上限的明确批准。 + 如果 provider 控制的维度没有已记录的最大上限,不得把最低值或示例当作批准上限, + 也不得按先批准后执行合同调用该端点。 不得为了价格发现、"probe"、"test" 或“先探一下”而调用 SimilarWeb 数据 endpoint。 diff --git a/zh/evaluate/pricing.mdx b/zh/evaluate/pricing.mdx index f23f9838..d13b5ccb 100644 --- a/zh/evaluate/pricing.mdx +++ b/zh/evaluate/pricing.mdx @@ -58,9 +58,10 @@ AIsa 对模型推理和计费型 API 能力采用按量计费。具体价格取 ## 上线前的验证 +- 对 SimilarWeb,不得通过 SimilarWeb 请求发现价格或验证配置。必须先展示精确 scope、公式和已记录的最大上限,再取得明确批准;如果没有已记录的最大上限,不得按先批准后执行合同调用该端点。 - 确认精确的模型 ID 或 endpoint。 - 查看当前的计价单位。 -- 跑一个有代表性的小请求。 +- 对 SimilarWeb 之外的 API,跑一个有代表性的小请求。 - 检查用量记录。 - 衡量完整工作流,而不只是单次调用。 - 在放量之前先加上预算告警。 diff --git a/zh/guides/pricing/similarweb.mdx b/zh/guides/pricing/similarweb.mdx index dfd6dde3..fed7534c 100644 --- a/zh/guides/pricing/similarweb.mdx +++ b/zh/guides/pricing/similarweb.mdx @@ -78,8 +78,8 @@ SimilarWeb 使用两阶段 credit 模型:网关可以在 `X-AISA-Estimated-Cre - **Credit 费率:** `1 credit / (metric x month)`,每 credit `$0.10`。 - **公式:** `credits = 1 x metrics x periods`。 - **费用驱动因素:** `metrics`:请求的指标数量;`periods`:日期范围内的月份数。 -- **Provider 控制的计价表示例:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`。对于该端点,`metrics`、`periods` 由 provider 控制,不能由调用方作为请求参数选择。 -- **控制方式:** 公式包含由 provider 控制且不能作为请求参数传入的维度(`metrics`、`periods`)。请把公开示例视为已记录的成本暴露,并在执行前取得预算确认。 +- **Provider 控制的最低示例:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`。对于该端点,`metrics`、`periods` 由 provider 控制,不能由调用方作为请求参数选择。 +- **控制方式:** 公式包含由 provider 控制且不能作为请求参数传入的维度(`metrics`、`periods`)。文档没有公开上限,因此示例只是最低值,不能作为批准上限。在有已记录的最大上限前,不得按先批准后执行合同调用该端点。 ### [Website Traffic Trend](/api-reference/similarweb/get_similarweb-website-traffic-trend) @@ -88,8 +88,8 @@ SimilarWeb 使用两阶段 credit 模型:网关可以在 `X-AISA-Estimated-Cre - **Credit 费率:** `1 credit / (metric x month)`,每 credit `$0.10`。 - **公式:** `credits = 1 x metrics x periods`。 - **费用驱动因素:** `metrics`:请求的指标数量;`periods`:日期范围内的月份数。 -- **Provider 控制的计价表示例:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`。对于该端点,`metrics`、`periods` 由 provider 控制,不能由调用方作为请求参数选择。 -- **控制方式:** 公式包含由 provider 控制且不能作为请求参数传入的维度(`metrics`、`periods`)。请把公开示例视为已记录的成本暴露,并在执行前取得预算确认。 +- **Provider 控制的最低示例:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`。对于该端点,`metrics`、`periods` 由 provider 控制,不能由调用方作为请求参数选择。 +- **控制方式:** 公式包含由 provider 控制且不能作为请求参数传入的维度(`metrics`、`periods`)。文档没有公开上限,因此示例只是最低值,不能作为批准上限。在有已记录的最大上限前,不得按先批准后执行合同调用该端点。 ## 按返回行数计费 From 6e4c7c68ddc09b46e37b0e03f36a42e5f4fe71a5 Mon Sep 17 00:00:00 2001 From: idan Date: Wed, 2 Sep 2026 12:18:51 +0800 Subject: [PATCH 5/8] docs: generalize paid API approval guidance --- README.md | 6 +- agent-quickstart.mdx | 29 +-- docs.json | 6 +- evaluate/pricing.mdx | 4 +- guides/pricing.mdx | 4 +- guides/pricing/per-call-api-pricing.mdx | 2 +- guides/pricing/similarweb.mdx | 256 -------------------- llms.txt | 9 +- openapi/similarweb.json | 46 ++-- scripts/check_similarweb_pricing.py | 52 +--- scripts/generate_similarweb_pricing_docs.py | 227 +---------------- scripts/validate_similarweb_mintlify.py | 16 +- zh/agent-quickstart.mdx | 21 +- zh/evaluate/pricing.mdx | 4 +- zh/guides/pricing.mdx | 4 +- zh/guides/pricing/per-call-api-pricing.mdx | 2 +- zh/guides/pricing/similarweb.mdx | 256 -------------------- 17 files changed, 88 insertions(+), 856 deletions(-) delete mode 100644 guides/pricing/similarweb.mdx delete mode 100644 zh/guides/pricing/similarweb.mdx diff --git a/README.md b/README.md index 3a2af99b..7b521272 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,9 @@ python3 scripts/generate_similarweb_pricing_docs.py --write python3 scripts/generate_similarweb_pricing_docs.py --check ``` -The generator deliberately derives the endpoint copy and English/Chinese -guides from the OpenAPI metadata so no second hand-authored rate schedule can -drift from the agent-facing contract. +The generator deliberately derives the endpoint copy from the OpenAPI metadata +so no second hand-authored rate schedule can drift from the agent-facing +contract. After the generated `openapi.yaml` commit is pushed to `main`, the workflow sends a `docs_openapi_updated` repository dispatch to diff --git a/agent-quickstart.mdx b/agent-quickstart.mdx index 7b14dcfb..cdd739e6 100644 --- a/agent-quickstart.mdx +++ b/agent-quickstart.mdx @@ -10,31 +10,32 @@ This page helps locate the relevant technical source. Reading it is not independ Goal: get the agent to the smallest verifiable next step without loading broad documentation indexes. -## IMPORTANT: SimilarWeb approval-first contract + +## IMPORTANT: Paid and high-cost API approval-first contract -This contract applies to every SimilarWeb **data** endpoint, whether it is invoked directly under `/apis/v1/similarweb/...` or through a SimilarWeb MCP data tool. It is a safety boundary, not a price discovery workflow. +This contract applies to every paid, dynamically priced, or potentially high-cost API endpoint, whether invoked directly, through an Agent Skill, or through an MCP data tool. It is a safety boundary, not a price discovery workflow. ```xml - + ``` -The matching endpoint's [`x-aisa-pricing`](https://aisa.one/openapi.yaml) metadata and [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb) are the published pricing source of truth. They provide the formula and documented exposure; they do not create a quote API or authorize a data call. +**Classic example — SimilarWeb:** SimilarWeb is a dynamic, potentially high-cost data API. Read the matching endpoint's [`x-aisa-pricing`](https://aisa.one/openapi.yaml) metadata, calculate the chosen request's cost only when its dimensions are bounded, and obtain explicit approval before the data call. The metadata provides a formula and documented exposure; it does not create a quote API or authorize a request. ## Minimal setup facts diff --git a/docs.json b/docs.json index bf7549a7..7da62032 100644 --- a/docs.json +++ b/docs.json @@ -127,8 +127,7 @@ "pages": [ "guides/pricing", "guides/pricing/ai-model-pricing-llm-inference", - "guides/pricing/per-call-api-pricing", - "guides/pricing/similarweb" + "guides/pricing/per-call-api-pricing" ] }, { @@ -2146,8 +2145,7 @@ "pages": [ "zh/guides/pricing", "zh/guides/pricing/ai-model-pricing-llm-inference", - "zh/guides/pricing/per-call-api-pricing", - "zh/guides/pricing/similarweb" + "zh/guides/pricing/per-call-api-pricing" ] }, { diff --git a/evaluate/pricing.mdx b/evaluate/pricing.mdx index 1f81b094..82c9606f 100644 --- a/evaluate/pricing.mdx +++ b/evaluate/pricing.mdx @@ -11,7 +11,7 @@ Use current pricing sources for final decisions. - [AI Model Pricing](/guides/pricing/ai-model-pricing-llm-inference) for model-pricing guidance. - [Per-call API Pricing](/guides/pricing/per-call-api-pricing) for API billing guidance. -- [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb) for SimilarWeb's formula-based endpoint pricing. +- The matching SimilarWeb endpoint documentation and its `x-aisa-pricing` metadata for SimilarWeb's formula-based endpoint pricing. - [Wallet and Payments](/guides/pricing/wallet) for funding and balance behavior. - [Usage Logs](/guides/dashboard/usage-logs) for observed account usage. - The live model catalog or exact API page for current capability context. @@ -58,7 +58,7 @@ A direct provider can be the simpler option for a stable, single-provider worklo ## Verify before production -- For SimilarWeb, do not run a SimilarWeb request to discover price or validate setup. First present the exact scope, formula, and documented maximum, then obtain explicit approval. If there is no documented upper bound, do not execute that endpoint under the approval-first contract. +- For any paid or potentially high-cost API, do not run a request to discover price or validate setup. First present the exact scope, formula or price rule, and documented maximum, then obtain explicit approval. SimilarWeb is a classic dynamic-cost example; if it has no documented upper bound, do not execute that endpoint under the approval-first contract. - Confirm the exact model ID or endpoint. - Check current price units. - For APIs other than SimilarWeb, run a small representative request. diff --git a/guides/pricing.mdx b/guides/pricing.mdx index 03728d37..828d201c 100644 --- a/guides/pricing.mdx +++ b/guides/pricing.mdx @@ -60,9 +60,9 @@ This pricing model applies to APIs such as: For endpoint-level pricing details and billing behavior, see [Per-Call API Pricing](/guides/pricing/per-call-api-pricing). -### SimilarWeb: formula-based pricing +### Formula-priced data APIs -SimilarWeb is a paid data API with a credit formula. Depending on the endpoint, cost can be fixed, driven by request dimensions, or driven by returned rows. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb) before a paid request; it shows the current formula, cost driver, example, and endpoint-specific control. +Some paid data APIs, including SimilarWeb, use a credit formula rather than a fixed per-call price. Read the matching endpoint documentation and its machine-readable pricing declaration before a paid request; calculate the selected scope only when it has a documented maximum, then obtain explicit approval. ## Choosing the Correct Pricing Model diff --git a/guides/pricing/per-call-api-pricing.mdx b/guides/pricing/per-call-api-pricing.mdx index 38089731..c4674350 100644 --- a/guides/pricing/per-call-api-pricing.mdx +++ b/guides/pricing/per-call-api-pricing.mdx @@ -8,7 +8,7 @@ excerpt: >- This page explains the fixed-price model for eligible non-LLM APIs available through AIsa. - **IMPORTANT:** This page does not make every data API fixed-price. SimilarWeb endpoints may be fixed, priced per returned row, or priced from request dimensions. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb) before a paid SimilarWeb request. + **IMPORTANT:** This page does not make every data API fixed-price. Some paid data APIs, including SimilarWeb, are priced from request dimensions or returned rows. Read the matching endpoint documentation and published pricing declaration before a paid request, then obtain explicit approval when the cost can be material. ![Tavily Search API page on AIsa showing each endpoint with its flat per-call price](/images/6bd32ad1-tavily-search-per-call.png) diff --git a/guides/pricing/similarweb.mdx b/guides/pricing/similarweb.mdx deleted file mode 100644 index b69464ca..00000000 --- a/guides/pricing/similarweb.mdx +++ /dev/null @@ -1,256 +0,0 @@ ---- -title: SimilarWeb Pricing & Cost Control -excerpt: >- - Machine-derived SimilarWeb credit formulas, examples, and cost controls - for people and agents before a paid request. ---- - -SimilarWeb is a paid data API with credit-based pricing. Its catalog display value is not always a fixed, request-specific quote. - - - **IMPORTANT — approval-first:** A SimilarWeb data endpoint is not price discovery. Before any data request, use the matching `x-aisa-pricing` disclosure to state the exact scope, formula, and documented maximum exposure; then obtain explicit user approval for that scope and cap. Never send an unapproved probe, test, or "just check" request. Docs, `/v1/models`, and MCP discovery are allowed discovery surfaces. - - -This page is generated from each endpoint's `x-aisa-pricing` object in the [machine-readable OpenAPI](https://aisa.one/openapi.yaml). It intentionally does not maintain a second hand-authored rate schedule. - -## How settlement works - -SimilarWeb uses a two-phase credit model: the gateway can report a pre-authorization estimate in `X-AISA-Estimated-Credits`, then reports settled usage in `X-AISA-Accounted-Credits` and `X-AISA-Price-USD`. The provider-level API contract says that only successful, non-empty responses are billed. These formulas and examples describe the published schedule; they are not a server-authoritative quote endpoint. - -Do not treat a catalog `pricing.normal` value of `0` as a free SimilarWeb request. - -## Request-dimension pricing - - -### [Traffic & Engagement](/api-reference/similarweb/get_similarweb-website-traffic-engagement) - -- **Pricing mode:** request-dimension credit pricing. -- **Credit rate:** `1 credit / (metric x month)` at `$0.10` per credit. -- **Formula:** `credits = 1 x metrics x periods`. -- **Cost drivers:** `metrics`: number of metrics requested; `periods`: number of months in the date window. -- **Current schedule example:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods.` -- **Control:** Cost varies with `metrics`, the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. - - -### [Website Ranking](/api-reference/similarweb/get_similarweb-website-ranking) - -- **Pricing mode:** request-dimension credit pricing. -- **Credit rate:** `2 credits / (month)` at `$0.10` per credit. -- **Formula:** `credits = 2 x periods`. -- **Cost drivers:** `periods`: number of months in the date window. -- **Current schedule example:** `minimal (1 month) = 2 credits ($0.20); cost grows with periods.` -- **Control:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. - - -### [PPC Spend](/api-reference/similarweb/get_similarweb-website-ppc-spend) - -- **Pricing mode:** request-dimension credit pricing. -- **Credit rate:** `1 credit / (month)` at `$0.10` per credit. -- **Formula:** `credits = 1 x periods`. -- **Cost drivers:** `periods`: number of months in the date window. -- **Current schedule example:** `minimal (1 month) = 1 credit ($0.10); cost grows with periods.` -- **Control:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. - - -### [Marketing Channel Sources](/api-reference/similarweb/get_similarweb-website-marketing-channel-sources-legacy) - -- **Pricing mode:** request-dimension credit pricing. -- **Credit rate:** `7 credits / (month)` at `$0.10` per credit. -- **Formula:** `credits = 7 x periods`. -- **Cost drivers:** `periods`: number of months in the date window. -- **Current schedule example:** `minimal (1 month) = 7 credits ($0.70); cost grows with periods.` -- **Control:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. - - -### [Deduplicated Audience](/api-reference/similarweb/get_similarweb-website-deduplicated-audience) - -- **Pricing mode:** request-dimension credit pricing. -- **Credit rate:** `7 credits / (month)` at `$0.10` per credit. -- **Formula:** `credits = 7 x periods`. -- **Cost drivers:** `periods`: number of months in the date window. -- **Current schedule example:** `minimal (1 month) = 7 credits ($0.70); cost grows with periods.` -- **Control:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. - - -### [Website Traffic Snapshot](/api-reference/similarweb/get_similarweb-website-traffic-snapshot) - -- **Pricing mode:** request-dimension credit pricing. -- **Credit rate:** `1 credit / (metric x month)` at `$0.10` per credit. -- **Formula:** `credits = 1 x metrics x periods`. -- **Cost drivers:** `metrics`: number of metrics requested; `periods`: number of months in the date window. -- **Provider-controlled lower-bound example:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters. -- **Control:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. - - -### [Website Traffic Trend](/api-reference/similarweb/get_similarweb-website-traffic-trend) - -- **Pricing mode:** request-dimension credit pricing. -- **Credit rate:** `1 credit / (metric x month)` at `$0.10` per credit. -- **Formula:** `credits = 1 x metrics x periods`. -- **Cost drivers:** `metrics`: number of metrics requested; `periods`: number of months in the date window. -- **Provider-controlled lower-bound example:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters. -- **Control:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. - -## Returned-row pricing - - -### [Top Sites Ranking](/api-reference/similarweb/get_similarweb-website-top-sites-ranking) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `1 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(1 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 1 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [Referrals](/api-reference/similarweb/get_similarweb-website-referrals) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `4 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(4 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 4 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [Ad Networks](/api-reference/similarweb/get_similarweb-website-ad-networks) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `3 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(3 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [SimilarSites](/api-reference/similarweb/get_similarweb-website-similar-sites) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `5 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(5 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [Audience Interest](/api-reference/similarweb/get_similarweb-website-audience-interest) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `5 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(5 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [Audience Overlap](/api-reference/similarweb/get_similarweb-website-audience-overlap) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `2 / row (max 5 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(2 x rows); rows capped at 5`. -- **Cost drivers:** `limit`: charge scales with rows returned at 2 credit/row; at most 5 rows are billed. -- **Published maximum-exposure example:** `5 rows = 10 credits ($1.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`. -- **Control:** This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. - - -### [Popular Pages](/api-reference/similarweb/get_similarweb-website-popular-pages) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `3 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(3 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [Website Subdomains](/api-reference/similarweb/get_similarweb-website-subdomains) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `2 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(2 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 2 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [Keyword Competitors](/api-reference/similarweb/get_similarweb-search-keyword-competitors) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `0.03 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(0.03 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 0.03 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [Website Keywords](/api-reference/similarweb/get_similarweb-search-website-keywords) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `0.1 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(0.1 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [SERP Players - Clicks over time](/api-reference/similarweb/get_similarweb-search-serp-players-timeseries) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `0.02 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(0.02 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 0.02 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [SERP Players - Aggregated](/api-reference/similarweb/get_similarweb-search-serp-players-aggregated) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `0.07 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(0.07 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 0.07 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [Landing Pages](/api-reference/similarweb/get_similarweb-search-landing-pages) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `0.1 / row (max 20 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(0.1 x rows); rows capped at 20`. -- **Cost drivers:** `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. -- **Current schedule example:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` -- **Control:** Use the smallest meaningful `limit`; returned rows drive the credit cost. - - -### [Website Top Geographies](/api-reference/similarweb/get_similarweb-website-top-geographies) - -- **Pricing mode:** returned-row credit pricing. -- **Credit rate:** `3 / row (max 10 rows)` at `$0.10` per credit. -- **Formula:** `credits = ceil(3 x rows); rows capped at 10`. -- **Cost drivers:** `limit`: charge scales with rows returned at 3 credit/row; at most 10 rows are billed. -- **Published maximum-exposure example:** `10 rows = 30 credits ($3.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`. -- **Control:** This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. - -## Fixed per-request pricing - - -### [Demographics](/api-reference/similarweb/get_similarweb-website-demographics) - -- **Pricing mode:** fixed per request. -- **Credit rate:** `8 credits (fixed)` at `$0.10` per credit. -- **Formula:** `credits = 8 (fixed per request)`. -- **Cost drivers:** `(none)`: flat per-request credit charge. -- **Current schedule example:** `1 request = 8 credits ($0.80)` -- **Control:** The published credit charge is fixed for this request type. - - -### [Website Technologies](/api-reference/similarweb/get_similarweb-website-technologies) - -- **Pricing mode:** fixed per request. -- **Credit rate:** `10 credits (fixed)` at `$0.10` per credit. -- **Formula:** `credits = 10 (fixed per request)`. -- **Cost drivers:** `(none)`: flat per-request credit charge. -- **Current schedule example:** `1 request = 10 credits ($1.00)` -- **Control:** The published credit charge is fixed for this request type. diff --git a/llms.txt b/llms.txt index 670f2b06..d504f0e0 100644 --- a/llms.txt +++ b/llms.txt @@ -10,12 +10,11 @@ Use this index to choose the smallest relevant documentation set. For product di - [Getting Started](https://aisa.one/docs/guides/getting-started-with-aisa): account, API key, and first-request setup. - [Authentication](https://aisa.one/docs/guides/authentication): Bearer tokens, key storage, and rotation. - [Pricing and Billing](https://aisa.one/docs/guides/pricing): model and per-call API billing entry point. -- [SimilarWeb Pricing & Cost Control](https://aisa.one/docs/guides/pricing/similarweb): machine-derived credit formulas, examples, and required scope controls for paid SimilarWeb endpoints. - [Errors](https://aisa.one/docs/api-reference/errors): error formats and handling. - [Rate Limits](https://aisa.one/docs/api-reference/rate-limits): limits and relevant headers. - -For any SimilarWeb data endpoint, first read the matching `x-aisa-pricing` disclosure and Pricing & Cost Control page. You may read docs, `/v1/models`, and MCP discovery before approval, but a SimilarWeb data endpoint is not price discovery. Before a data call, present the exact scope, pricing formula, and documented maximum USD exposure; obtain the user's explicit approval for that scope and cap. If provider-controlled dimensions have no documented upper bound, a minimum/example is not a cap and the endpoint must not execute under this approval-first contract. Never send an unapproved probe, test, or "just check" request, and do not invent a quote API. If the scope or maximum changes, request new approval. + ## Navigate by Goal @@ -57,7 +56,7 @@ For any SimilarWeb data endpoint, first read the matching `x-aisa-pricing` discl - [Twitter API](https://aisa.one/docs/api-reference/twitter/get_twitter-user-info): X/Twitter read and authenticated write routes. - [Scholar API](https://aisa.one/docs/api-reference/scholar/post_scholar-search-scholar): academic and mixed-source search. - [Prediction Market API](https://aisa.one/docs/api-reference/prediction-market/get_polymarket-events): Polymarket and Kalshi data. -- [SimilarWeb API](https://aisa.one/docs/api-reference/similarweb/get_similarweb-website-similar-sites): digital-intelligence data; load SimilarWeb pricing guidance before a paid call. +- [SimilarWeb API](https://aisa.one/docs/api-reference/similarweb/get_similarweb-website-similar-sites): digital-intelligence data; read the matching endpoint's `x-aisa-pricing` metadata before a paid call. ## Machine Discovery @@ -74,4 +73,4 @@ For any SimilarWeb data endpoint, first read the matching `x-aisa-pricing` discl - Treat search results as discovery, fetched pages as evidence, and generated text as synthesis. - Separate read operations from writes and payments; verify authorization before side effects. - Check live availability, status, pricing, and authentication before relying on a capability. -- For SimilarWeb, follow the approval-first contract above: load the matching endpoint and [SimilarWeb Pricing & Cost Control](https://aisa.one/docs/guides/pricing/similarweb), state the formula and documented maximum exposure, then request explicit approval before the data call. Do not treat a catalog display value as a request-specific quote. +- For SimilarWeb, follow the paid-API approval-first contract above: load the matching endpoint and `x-aisa-pricing` metadata, state the formula and documented maximum exposure, then request explicit approval before the data call. Do not treat a catalog display value as a request-specific quote. diff --git a/openapi/similarweb.json b/openapi/similarweb.json index 55d4df4a..176d5d09 100644 --- a/openapi/similarweb.json +++ b/openapi/similarweb.json @@ -38,7 +38,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Traffic & Engagement", - "description": "Traffic & Engagement. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Current schedule example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods.`\n\n**IMPORTANT:** Cost varies with `metrics`, the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#traffic-engagement) before a paid request.\n\n", + "description": "Traffic & Engagement. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Current schedule example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods.`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Cost varies with `metrics`, the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_traffic_engagement", "parameters": [ { @@ -274,7 +274,7 @@ "example": "minimal (1 month) = 2 credits ($0.20); cost grows with periods." }, "summary": "Website Ranking", - "description": "Website Ranking. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 credits / (month)` at `$0.10` per credit. Formula: `credits = 2 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 2 credits ($0.20); cost grows with periods.`\n\n**IMPORTANT:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#ranking) before a paid request.\n\n", + "description": "Website Ranking. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 credits / (month)` at `$0.10` per credit. Formula: `credits = 2 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 2 credits ($0.20); cost grows with periods.`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_ranking", "parameters": [ { @@ -464,7 +464,7 @@ "example": "minimal (1 month) = 1 credit ($0.10); cost grows with periods." }, "summary": "PPC Spend", - "description": "PPC Spend. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (month)` at `$0.10` per credit. Formula: `credits = 1 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 1 credit ($0.10); cost grows with periods.`\n\n**IMPORTANT:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#ppc-spend) before a paid request.\n\n", + "description": "PPC Spend. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (month)` at `$0.10` per credit. Formula: `credits = 1 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 1 credit ($0.10); cost grows with periods.`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_ppc_spend", "parameters": [ { @@ -648,7 +648,7 @@ "example": "20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)" }, "summary": "Top Sites Ranking", - "description": "Top Sites Ranking. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#top-sites-ranking) before a paid request.\n\n", + "description": "Top Sites Ranking. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_top_sites_ranking", "parameters": [ { @@ -797,7 +797,7 @@ "example": "minimal (1 month) = 7 credits ($0.70); cost grows with periods." }, "summary": "Marketing Channel Sources", - "description": "Marketing Channel Sources. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 7 credits ($0.70); cost grows with periods.`\n\n**IMPORTANT:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#marketing-channel-sources-legacy) before a paid request.\n\n", + "description": "Marketing Channel Sources. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 7 credits ($0.70); cost grows with periods.`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_marketing_channel_sources_legacy", "parameters": [ { @@ -995,7 +995,7 @@ "example": "20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)" }, "summary": "Referrals", - "description": "Referrals. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `4 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(4 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 4 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#referrals) before a paid request.\n\n", + "description": "Referrals. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `4 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(4 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 4 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_referrals", "parameters": [ { @@ -1215,7 +1215,7 @@ "example": "20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)" }, "summary": "Ad Networks", - "description": "Ad Networks. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#ad-networks) before a paid request.\n\n", + "description": "Ad Networks. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_ad_networks", "parameters": [ { @@ -1436,7 +1436,7 @@ "example": "20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)" }, "summary": "SimilarSites", - "description": "SimilarSites. Response follows the SimilarWeb v5 envelope (meta + data). Date window (upstream SimilarWeb constraint): start_date and end_date must span EXACTLY 3 consecutive months — a 1- or 2-month span is rejected with upstream error 120 ('must span exactly 3 month(s)'). That span must also be SimilarWeb's most recent supported window, which advances forward each month; an older or out-of-range span is rejected with error 101 ('Dates not in range'). In practice, request the three most recent completed months (e.g. if the latest published month is 2026-07, use start_date=2026-05 and end_date=2026-07). To read the exact currently-supported range, call SimilarWeb's /describe endpoint for this API.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#similar-sites) before a paid request.\n\n", + "description": "SimilarSites. Response follows the SimilarWeb v5 envelope (meta + data). Date window (upstream SimilarWeb constraint): start_date and end_date must span EXACTLY 3 consecutive months — a 1- or 2-month span is rejected with upstream error 120 ('must span exactly 3 month(s)'). That span must also be SimilarWeb's most recent supported window, which advances forward each month; an older or out-of-range span is rejected with error 101 ('Dates not in range'). In practice, request the three most recent completed months (e.g. if the latest published month is 2026-07, use start_date=2026-05 and end_date=2026-07). To read the exact currently-supported range, call SimilarWeb's /describe endpoint for this API.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_similar_sites", "parameters": [ { @@ -1662,7 +1662,7 @@ "example": "1 request = 8 credits ($0.80)" }, "summary": "Demographics", - "description": "Demographics. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must fall in the SAME month (exactly one monthly bucket).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `8 credits (fixed)` at `$0.10` per credit. Formula: `credits = 8 (fixed per request)`. Cost drivers: `(none)`: flat per-request credit charge. Current schedule example: `1 request = 8 credits ($0.80)`\n\n**IMPORTANT:** The published credit charge is fixed for this request type. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#demographics) before a paid request.\n\n", + "description": "Demographics. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must fall in the SAME month (exactly one monthly bucket).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `8 credits (fixed)` at `$0.10` per credit. Formula: `credits = 8 (fixed per request)`. Cost drivers: `(none)`: flat per-request credit charge. Current schedule example: `1 request = 8 credits ($0.80)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. The published credit charge is fixed for this request type. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_demographics", "parameters": [ { @@ -1880,7 +1880,7 @@ "example": "minimal (1 month) = 7 credits ($0.70); cost grows with periods." }, "summary": "Deduplicated Audience", - "description": "Deduplicated Audience. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 7 credits ($0.70); cost grows with periods.`\n\n**IMPORTANT:** Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#deduplicated-audience) before a paid request.\n\n", + "description": "Deduplicated Audience. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 7 credits ($0.70); cost grows with periods.`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_deduplicated_audience", "parameters": [ { @@ -2090,7 +2090,7 @@ "example": "20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)" }, "summary": "Audience Interest", - "description": "Audience Interest. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#audience-interest) before a paid request.\n\n", + "description": "Audience Interest. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_audience_interest", "parameters": [ { @@ -2320,7 +2320,7 @@ "example": "5 rows = 10 credits ($1.00); limit=5 = 10 credits ($1.00)" }, "summary": "Audience Overlap", - "description": "Audience Overlap. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 / row (max 5 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 5`. Cost drivers: `limit`: charge scales with rows returned at 2 credit/row; at most 5 rows are billed. Published maximum-exposure example: `5 rows = 10 credits ($1.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`.\n\n**IMPORTANT:** This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#audience-overlap) before a paid request.\n\n", + "description": "Audience Overlap. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 / row (max 5 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 5`. Cost drivers: `limit`: charge scales with rows returned at 2 credit/row; at most 5 rows are billed. Published maximum-exposure example: `5 rows = 10 credits ($1.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`.\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_audience_overlap", "parameters": [ { @@ -2481,7 +2481,7 @@ "example": "1 request = 10 credits ($1.00)" }, "summary": "Website Technologies", - "description": "Website Technologies. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must be the SAME month, and that month must be the latest available data month — a single monthly bucket that advances as SimilarWeb refreshes its data, and which may differ by country. Supplying any other month returns SimilarWeb error_code 101 (\"Dates not in range\"); the error message states the currently-allowed range.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `10 credits (fixed)` at `$0.10` per credit. Formula: `credits = 10 (fixed per request)`. Cost drivers: `(none)`: flat per-request credit charge. Current schedule example: `1 request = 10 credits ($1.00)`\n\n**IMPORTANT:** The published credit charge is fixed for this request type. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#technologies) before a paid request.\n\n", + "description": "Website Technologies. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must be the SAME month, and that month must be the latest available data month — a single monthly bucket that advances as SimilarWeb refreshes its data, and which may differ by country. Supplying any other month returns SimilarWeb error_code 101 (\"Dates not in range\"); the error message states the currently-allowed range.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `10 credits (fixed)` at `$0.10` per credit. Formula: `credits = 10 (fixed per request)`. Cost drivers: `(none)`: flat per-request credit charge. Current schedule example: `1 request = 10 credits ($1.00)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. The published credit charge is fixed for this request type. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_technologies", "parameters": [ { @@ -2710,7 +2710,7 @@ "example": "20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)" }, "summary": "Popular Pages", - "description": "Popular Pages. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#popular-pages) before a paid request.\n\n", + "description": "Popular Pages. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_popular_pages", "parameters": [ { @@ -2931,7 +2931,7 @@ "example": "20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)" }, "summary": "Website Subdomains", - "description": "Website Subdomains. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 2 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#subdomains) before a paid request.\n\n", + "description": "Website Subdomains. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 2 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_subdomains", "parameters": [ { @@ -3142,7 +3142,7 @@ "example": "20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)" }, "summary": "Keyword Competitors", - "description": "Keyword Competitors. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.03 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.03 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.03 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#keyword-competitors) before a paid request.\n\n", + "description": "Keyword Competitors. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.03 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.03 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.03 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_keyword_competitors", "parameters": [ { @@ -3360,7 +3360,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "Website Keywords", - "description": "Website Keywords. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 3 monthly buckets. Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-keywords) before a paid request.\n\n", + "description": "Website Keywords. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 3 monthly buckets. Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_keywords", "parameters": [ { @@ -3623,7 +3623,7 @@ "example": "20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)" }, "summary": "SERP Players - Clicks over time", - "description": "SERP Players - Clicks over time. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.02 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.02 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.02 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#serp-players-timeseries) before a paid request.\n\n", + "description": "SERP Players - Clicks over time. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.02 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.02 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.02 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_serp_players_timeseries", "parameters": [ { @@ -3807,7 +3807,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "SERP Players - Aggregated", - "description": "SERP Players - Aggregated. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.07 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.07 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.07 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#serp-players-aggregated) before a paid request.\n\n", + "description": "SERP Players - Aggregated. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.07 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.07 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.07 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_serp_players_aggregated", "parameters": [ { @@ -4021,7 +4021,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "Landing Pages", - "description": "Landing Pages. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#landing-pages) before a paid request.\n\n", + "description": "Landing Pages. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_landing_pages", "parameters": [ { @@ -4272,7 +4272,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Website Traffic Snapshot", - "description": "Latest-month traffic snapshot for a domain: visits plus core engagement metrics (average visit duration, bounce rate, pages per visit) in a single object. The most recent available month is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled lower-bound example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-traffic-snapshot) before a paid request.\n\n", + "description": "Latest-month traffic snapshot for a domain: visits plus core engagement metrics (average visit duration, bounce rate, pages per visit) in a single object. The most recent available month is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled lower-bound example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_website_traffic_snapshot", "parameters": [ { @@ -4435,7 +4435,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Website Traffic Trend", - "description": "Monthly traffic time series for a domain over the recent available window (data.points, one entry per month). The window is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled lower-bound example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-traffic-trend) before a paid request.\n\n", + "description": "Monthly traffic time series for a domain over the recent available window (data.points, one entry per month). The window is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled lower-bound example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_website_traffic_trend", "parameters": [ { @@ -4633,7 +4633,7 @@ "example": "10 rows = 30 credits ($3.00); limit=5 = 15 credits ($1.50)" }, "summary": "Website Top Geographies", - "description": "Top countries by share of a domain's traffic for the latest available month (data.countries, up to 10 rows with country_code, country_name, share and visits). Geography coverage is worldwide (ww) and fixed: a country parameter is not accepted for this endpoint.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 10 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 10`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 10 rows are billed. Published maximum-exposure example: `10 rows = 30 credits ($3.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`.\n\n**IMPORTANT:** This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#website-top-geographies) before a paid request.\n\n", + "description": "Top countries by share of a domain's traffic for the latest available month (data.countries, up to 10 rows with country_code, country_name, share and visits). Geography coverage is worldwide (ww) and fixed: a country parameter is not accepted for this endpoint.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 10 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 10`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 10 rows are billed. Published maximum-exposure example: `10 rows = 30 credits ($3.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`.\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", "operationId": "get_similarweb_website_top_geographies", "parameters": [ { diff --git a/scripts/check_similarweb_pricing.py b/scripts/check_similarweb_pricing.py index 843a12ec..a0ef265a 100644 --- a/scripts/check_similarweb_pricing.py +++ b/scripts/check_similarweb_pricing.py @@ -4,7 +4,6 @@ from __future__ import annotations import argparse -import json from pathlib import Path from typing import Any @@ -12,11 +11,9 @@ from generate_similarweb_pricing_docs import ( EXPECTED_OPERATION_IDS, - GUIDE_PATH, ROOT, SETTLEMENT_RESPONSE_HEADERS, SOURCE_PATH, - ZH_GUIDE_PATH, check_outputs, category, collect_operations, @@ -27,7 +24,6 @@ LLMS_PATH = ROOT / "llms.txt" -NAV_PATH = ROOT / "docs.json" AGENT_QUICKSTART_PATH = ROOT / "agent-quickstart.mdx" ZH_AGENT_QUICKSTART_PATH = ROOT / "zh" / "agent-quickstart.mdx" PRICING_OVERVIEW_PATH = ROOT / "guides" / "pricing.mdx" @@ -42,42 +38,24 @@ def fail(message: str) -> None: raise SystemExit(f"pricing contract check failed: {message}") -def contains(value: Any, wanted: str) -> bool: - if value == wanted: - return True - if isinstance(value, list): - return any(contains(item, wanted) for item in value) - if isinstance(value, dict): - return any(contains(item, wanted) for item in value.values()) - return False - - def check_checked_in_surfaces(source: dict[str, Any]) -> None: stale = check_outputs(expected_outputs(source)) if stale: paths = ", ".join(str(path.relative_to(ROOT)) for path in stale) fail(f"generated surfaces are stale: {paths}; run generate_similarweb_pricing_docs.py --write") - for guide in (GUIDE_PATH, ZH_GUIDE_PATH): - content = guide.read_text(encoding="utf-8") - if "IMPORTANT" not in content or "x-aisa-pricing" not in content: - fail(f"{guide.relative_to(ROOT)} lacks the required machine-derived warning") - operations = collect_operations(source) for operation in operations: endpoint = ROOT / "api-reference" / "similarweb" / f"{operation.endpoint_slug}.mdx" if not endpoint.exists(): fail(f"{operation.operation_id} has no endpoint documentation page") - for guide in (GUIDE_PATH, ZH_GUIDE_PATH): - content = guide.read_text(encoding="utf-8") - if f'' not in content: - fail(f"{guide.relative_to(ROOT)} has no anchor for {operation.operation_id}") - source_operation = source["paths"][operation.path][operation.method] description = source_operation["description"] response = source_operation.get("responses", {}).get("200") if not isinstance(response, dict) or response.get("headers") != SETTLEMENT_RESPONSE_HEADERS: fail(f"{operation.operation_id} lacks the generated settlement response headers") + if "/agent-quickstart#paid-api-approval-first" not in description: + fail(f"{operation.operation_id} does not route agents to the paid-API approval-first contract") uncontrolled = provider_controlled_drivers(operation) if category(operation) == "rows" and uncontrolled: if "does not accept `limit`" not in description: @@ -91,29 +69,22 @@ def check_checked_in_surfaces(source: dict[str, Any]) -> None: fail(f"{operation.operation_id} presents a provider-controlled lower bound as an approval cap") llms = LLMS_PATH.read_text(encoding="utf-8") - if "guides/pricing/similarweb" not in llms or "SimilarWeb Pricing & Cost Control" not in llms: - fail("llms.txt does not route agents to SimilarWeb pricing guidance") - for marker in ("", "explicit approval", "price discovery", "x-aisa-pricing", "/v1/models", "MCP discovery"): + for marker in ("", "explicit approval", "price discovery", "x-aisa-pricing", "/v1/models", "MCP discovery", "SimilarWeb is a classic"): if marker not in llms: - fail(f"llms.txt lacks SimilarWeb approval-first marker: {marker}") + fail(f"llms.txt lacks paid-API approval-first marker: {marker}") for path, markers in ( - (AGENT_QUICKSTART_PATH, ("", "explicit approval", "price discovery", "x-aisa-pricing", "/v1/models", "MCP discovery")), - (ZH_AGENT_QUICKSTART_PATH, ("", "明确批准", "价格发现", "x-aisa-pricing", "/v1/models", "MCP discovery")), + (AGENT_QUICKSTART_PATH, ("", "explicit approval", "price discovery", "published pricing source", "/v1/models", "MCP discovery", "Classic example — SimilarWeb")), + (ZH_AGENT_QUICKSTART_PATH, ("", "明确批准", "价格发现", "公开计价来源", "/v1/models", "MCP discovery", "典型场景 — SimilarWeb")), ): content = path.read_text(encoding="utf-8") for marker in markers: if marker not in content: fail(f"{path.relative_to(ROOT)} lacks SimilarWeb approval-first marker: {marker}") similar_sites = next(operation for operation in operations if operation.operation_id == "get_similarweb_similar_sites") - endpoint_url = f"https://aisa.one/docs{similar_sites.endpoint_url}" + endpoint_url = f"https://aisa.one/docs/api-reference/similarweb/{similar_sites.endpoint_slug}" if endpoint_url not in llms: fail("llms.txt SimilarWeb API family link does not resolve to the SimilarSites endpoint page") - navigation = json.loads(NAV_PATH.read_text(encoding="utf-8")) - for slug in ("guides/pricing/similarweb", "zh/guides/pricing/similarweb"): - if not contains(navigation, slug): - fail(f"docs navigation does not include {slug}") - english_overview = PRICING_OVERVIEW_PATH.read_text(encoding="utf-8") chinese_overview = ZH_PRICING_OVERVIEW_PATH.read_text(encoding="utf-8") if "All non-LLM APIs use a fixed per-request billing model." in english_overview: @@ -122,12 +93,13 @@ def check_checked_in_surfaces(source: dict[str, Any]) -> None: fail("Chinese pricing overview still classifies every non-LLM API as fixed-price") for path in (PRICING_OVERVIEW_PATH, PER_CALL_PATH, ZH_PRICING_OVERVIEW_PATH, ZH_PER_CALL_PATH): - if "similarweb" not in path.read_text(encoding="utf-8").lower(): - fail(f"{path.relative_to(ROOT)} does not link to SimilarWeb pricing guidance") + content = path.read_text(encoding="utf-8").lower() + if "similarweb" not in content or "endpoint" not in content: + fail(f"{path.relative_to(ROOT)} does not route formula-priced APIs to endpoint documentation") for path, markers in ( - (EVALUATE_PRICING_PATH, ("do not run a SimilarWeb request to discover price", "explicit approval")), - (ZH_EVALUATE_PRICING_PATH, ("不得通过 SimilarWeb 请求发现价格", "明确批准")), + (EVALUATE_PRICING_PATH, ("any paid or potentially high-cost API", "explicit approval", "SimilarWeb is a classic")), + (ZH_EVALUATE_PRICING_PATH, ("任何付费或可能高成本的 API", "明确批准", "SimilarWeb 是动态成本的典型场景")), ): content = path.read_text(encoding="utf-8") for marker in markers: diff --git a/scripts/generate_similarweb_pricing_docs.py b/scripts/generate_similarweb_pricing_docs.py index 08ecba81..df14fbb2 100644 --- a/scripts/generate_similarweb_pricing_docs.py +++ b/scripts/generate_similarweb_pricing_docs.py @@ -22,8 +22,6 @@ ROOT = Path(__file__).resolve().parents[1] SOURCE_PATH = ROOT / "openapi" / "similarweb.json" -GUIDE_PATH = ROOT / "guides" / "pricing" / "similarweb.mdx" -ZH_GUIDE_PATH = ROOT / "zh" / "guides" / "pricing" / "similarweb.mdx" API_REFERENCE_DIR = ROOT / "api-reference" / "similarweb" EXPECTED_OPERATION_IDS = frozenset( @@ -94,16 +92,6 @@ class Operation: pricing: dict[str, Any] parameter_names: frozenset[str] - @property - def anchor(self) -> str: - endpoint = self.path.rsplit("/", 1)[-1] - return endpoint if self.method == "get" else f"{self.method}-{endpoint}" - - @property - def endpoint_url(self) -> str: - return f"/api-reference/similarweb/{self.endpoint_slug}" - - def fail(message: str) -> None: raise ValueError(f"SimilarWeb pricing generation failed: {message}") @@ -274,30 +262,6 @@ def drivers_en(operation: Operation) -> str: ) -def effect_zh(effect: str) -> str: - exact = { - "number of metrics requested": "请求的指标数量", - "number of months in the date window": "日期范围内的月份数", - "flat per-request credit charge": "每次请求固定 credit 费用", - } - if effect in exact: - return exact[effect] - row_match = re.fullmatch( - r"charge scales with rows returned at (.+) credit/row; at most (\d+) rows are billed", - effect, - ) - if row_match: - return f"按返回行数以 {row_match.group(1)} credit/行累积计费,最多计 {row_match.group(2)} 行" - fail(f"cannot localize an unknown cost-driver effect: {effect!r}") - - -def drivers_zh(operation: Operation) -> str: - return ";".join( - f"`{driver['param']}`:{effect_zh(driver['effect'])}" - for driver in operation.pricing["cost_drivers"] - ) - - def driver_is_controllable(operation: Operation, driver_name: str) -> bool: if driver_name == "periods": return {"start_date", "end_date"}.issubset(operation.parameter_names) @@ -339,24 +303,6 @@ def display_example_en(operation: Operation) -> tuple[str, str]: return "Current schedule example", f"`{raw_example}`" -def display_example_zh(operation: Operation) -> tuple[str, str]: - raw_example = operation.pricing["example"] - uncontrolled = provider_controlled_drivers(operation) - if category(operation) == "rows" and uncontrolled: - exposure, _, _ = raw_example.partition("; limit=") - return ( - "公开最大成本暴露示例", - f"`{exposure}`。源数据中的 `limit=...` 仅用于说明计量,不是该端点接受的 `limit` 参数。", - ) - if category(operation) == "dimensions" and uncontrolled: - names = "、".join(f"`{name}`" for name in uncontrolled) - return ( - "Provider 控制的最低示例", - f"`{raw_example.rstrip('.')}`。对于该端点,{names} 由 provider 控制,不能由调用方作为请求参数选择。", - ) - return "当前公开示例", f"`{raw_example}`" - - def control_en(operation: Operation) -> str: operation_category = category(operation) if operation_category == "fixed": @@ -388,53 +334,6 @@ def control_en(operation: Operation) -> str: return result -def control_zh(operation: Operation) -> str: - operation_category = category(operation) - if operation_category == "fixed": - return "该类请求的公开 credit 费用是固定的。" - if operation_category == "rows": - if "limit" in operation.parameter_names: - return "返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。" - return ( - "该端点按返回行数计费,但没有已记录的 `limit` 参数。不要承诺调用方可通过 `limit` 降低费用;" - "应把公开示例和上限视为一次被接受请求的成本暴露。" - ) - controllable = controllable_drivers(operation) - uncontrolled = provider_controlled_drivers(operation) - if not controllable: - names = "、".join(f"`{name}`" for name in uncontrolled) - return ( - f"公式包含由 provider 控制且不能作为请求参数传入的维度({names})。" - "文档没有公开上限,因此示例只是最低值,不能作为批准上限。" - "在有已记录的最大上限前,不得按先批准后执行合同调用该端点。" - ) - control_names = "、".join( - "`start_date`/`end_date` 日期范围" if name == "periods" else f"`{name}`" - for name in controllable - ) - result = f"费用会随 {control_names} 变化;执行前请缩小到必要范围并取得预算确认。" - if uncontrolled: - names = "、".join(f"`{name}`" for name in uncontrolled) - result += f" {names} 仍由 provider 控制。" - return result - - -def mode_en(operation: Operation) -> str: - return { - "fixed": "fixed per request", - "rows": "returned-row credit pricing", - "dimensions": "request-dimension credit pricing", - }[category(operation)] - - -def mode_zh(operation: Operation) -> str: - return { - "fixed": "固定每请求 credit 计费", - "rows": "按返回行数 credit 计费", - "dimensions": "按请求维度 credit 计费", - }[category(operation)] - - def generated_disclosure(operation: Operation) -> str: pricing = operation.pricing example_label, example = display_example_en(operation) @@ -446,9 +345,9 @@ def generated_disclosure(operation: Operation) -> str: f"Formula: `{pricing['credit_formula']}`. Cost drivers: {drivers_en(operation)}. " f"{example_label}: {example}", "", - f"**IMPORTANT:** {control_en(operation)} " - f"Read [SimilarWeb Pricing & Cost Control](/guides/pricing/similarweb#{operation.anchor}) " - "before a paid request.", + "**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. " + f"{control_en(operation)} Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) " + "and obtain explicit approval before a paid request.", DISCLOSURE_END, ) ) @@ -484,130 +383,10 @@ def render_source(source: dict[str, Any], operations: list[Operation]) -> str: return json.dumps(rendered, indent=2, ensure_ascii=False) + "\n" -def operation_section_en(operation: Operation) -> str: - pricing = operation.pricing - example_label, example = display_example_en(operation) - return "\n".join( - ( - f'', - f"### [{operation.summary}]({operation.endpoint_url})", - "", - f"- **Pricing mode:** {mode_en(operation)}.", - f"- **Credit rate:** `{pricing['credit_rate']}` at `{price(pricing['credit_price_usd'])}` per credit.", - f"- **Formula:** `{pricing['credit_formula']}`.", - f"- **Cost drivers:** {drivers_en(operation)}.", - f"- **{example_label}:** {example}", - f"- **Control:** {control_en(operation)}", - "", - ) - ) - - -def operation_section_zh(operation: Operation) -> str: - pricing = operation.pricing - example_label, example = display_example_zh(operation) - return "\n".join( - ( - f'', - f"### [{operation.summary}]({operation.endpoint_url})", - "", - f"- **计费方式:** {mode_zh(operation)}。", - f"- **Credit 费率:** `{pricing['credit_rate']}`,每 credit `{price(pricing['credit_price_usd'])}`。", - f"- **公式:** `{pricing['credit_formula']}`。", - f"- **费用驱动因素:** {drivers_zh(operation)}。", - f"- **{example_label}:** {example}", - f"- **控制方式:** {control_zh(operation)}", - "", - ) - ) - - -def render_guide_en(operations: list[Operation]) -> str: - groups = ( - ("dimensions", "Request-dimension pricing"), - ("rows", "Returned-row pricing"), - ("fixed", "Fixed per-request pricing"), - ) - parts = [ - "---", - "title: SimilarWeb Pricing & Cost Control", - "excerpt: >-", - " Machine-derived SimilarWeb credit formulas, examples, and cost controls", - " for people and agents before a paid request.", - "---", - "", - "SimilarWeb is a paid data API with credit-based pricing. Its catalog display value is not always a fixed, request-specific quote.", - "", - "", - " **IMPORTANT — approval-first:** A SimilarWeb data endpoint is not price discovery. Before any data request, use the matching `x-aisa-pricing` disclosure to state the exact scope, formula, and documented maximum exposure; then obtain explicit user approval for that scope and cap. Never send an unapproved probe, test, or \"just check\" request. Docs, `/v1/models`, and MCP discovery are allowed discovery surfaces.", - "", - "", - "This page is generated from each endpoint's `x-aisa-pricing` object in the [machine-readable OpenAPI](https://aisa.one/openapi.yaml). It intentionally does not maintain a second hand-authored rate schedule.", - "", - "## How settlement works", - "", - "SimilarWeb uses a two-phase credit model: the gateway can report a pre-authorization estimate in `X-AISA-Estimated-Credits`, then reports settled usage in `X-AISA-Accounted-Credits` and `X-AISA-Price-USD`. The provider-level API contract says that only successful, non-empty responses are billed. These formulas and examples describe the published schedule; they are not a server-authoritative quote endpoint.", - "", - "Do not treat a catalog `pricing.normal` value of `0` as a free SimilarWeb request.", - "", - ] - for group, heading in groups: - members = [operation for operation in operations if category(operation) == group] - if not members: - continue - parts.extend((f"## {heading}", "")) - for operation in members: - parts.append(operation_section_en(operation).rstrip()) - parts.append("") - return "\n".join(parts).rstrip() + "\n" - - -def render_guide_zh(operations: list[Operation]) -> str: - groups = ( - ("dimensions", "按请求维度计费"), - ("rows", "按返回行数计费"), - ("fixed", "固定每请求计费"), - ) - parts = [ - "---", - "title: SimilarWeb 价格与成本控制", - "excerpt: >-", - " 从机器可读合同自动生成的 SimilarWeb credit 公式、示例与成本控制说明,", - " 供人和 Agent 在付费请求前使用。", - "---", - "", - "SimilarWeb 是付费数据 API,采用 credit 计费。目录展示值并不总是某次请求的固定、精确报价。", - "", - "", - " **重要(IMPORTANT,先批准后执行):** SimilarWeb 数据 endpoint 不是价格发现入口。发起任何数据请求前,请使用匹配的 `x-aisa-pricing` 说明明确 scope、公式和已记录的最大成本暴露,再取得用户对该 scope 与上限的明确批准。绝不能发送未经批准的 probe、test 或“先探一下”请求;docs、`/v1/models` 和 MCP discovery 可以作为发现入口。", - "", - "", - "本页从 [机器可读 OpenAPI](https://aisa.one/openapi.yaml) 中每个端点的 `x-aisa-pricing` 对象自动生成,故意不维护第二份手写费率表。", - "", - "## 如何结算", - "", - "SimilarWeb 使用两阶段 credit 模型:网关可以在 `X-AISA-Estimated-Credits` 中返回预授权估算,然后在 `X-AISA-Accounted-Credits` 和 `X-AISA-Price-USD` 中报告最终结算用量。provider 级 API 合同说明只有成功且非空的响应会计费。这里的公式和示例描述公开计价表,并不是服务端权威的报价接口。", - "", - "不要把目录中的 `pricing.normal = 0` 当成 SimilarWeb 免费调用。", - "", - ] - for group, heading in groups: - members = [operation for operation in operations if category(operation) == group] - if not members: - continue - parts.extend((f"## {heading}", "")) - for operation in members: - parts.append(operation_section_zh(operation).rstrip()) - parts.append("") - return "\n".join(parts).rstrip() + "\n" - - def expected_outputs(source: dict[str, Any]) -> dict[Path, str]: operations = collect_operations(source) return { SOURCE_PATH: render_source(source, operations), - GUIDE_PATH: render_guide_en(operations), - ZH_GUIDE_PATH: render_guide_zh(operations), } diff --git a/scripts/validate_similarweb_mintlify.py b/scripts/validate_similarweb_mintlify.py index 0905b94a..c6c20dbf 100644 --- a/scripts/validate_similarweb_mintlify.py +++ b/scripts/validate_similarweb_mintlify.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 -"""Validate the generated SimilarWeb documentation in a minimal Mintlify site. +"""Validate the SimilarWeb endpoint disclosure and approval contract in Mintlify. The full repository currently contains unrelated historical MDX parse warnings. -This script copies only the generated pricing guides, agent-quickstart policy -pages, all SimilarWeb endpoint pages, and their OpenAPI source into a temporary +This script copies the agent-quickstart policy pages, all SimilarWeb endpoint +pages, and their OpenAPI source into a temporary Mintlify project, then runs the same strict ``mint validate`` command used in CI. It validates the surfaces this pricing contract owns without mutating or suppressing diagnostics in the source repository. @@ -20,10 +20,6 @@ ROOT = Path(__file__).resolve().parents[1] -GUIDE_PATHS = ( - ROOT / "guides" / "pricing" / "similarweb.mdx", - ROOT / "zh" / "guides" / "pricing" / "similarweb.mdx", -) POLICY_PATHS = ( ROOT / "agent-quickstart.mdx", ROOT / "zh" / "agent-quickstart.mdx", @@ -43,7 +39,7 @@ def build_fixture(fixture_root: Path) -> int: if not endpoint_pages: raise SystemExit("Mintlify fixture has no SimilarWeb endpoint pages") - for path in (*GUIDE_PATHS, *POLICY_PATHS, *endpoint_pages, OPENAPI_PATH): + for path in (*POLICY_PATHS, *endpoint_pages, OPENAPI_PATH): if not path.exists(): raise SystemExit(f"Mintlify fixture input is missing: {path.relative_to(ROOT)}") copy_into_fixture(path, fixture_root) @@ -51,8 +47,6 @@ def build_fixture(fixture_root: Path) -> int: pages = [ "agent-quickstart", "zh/agent-quickstart", - "guides/pricing/similarweb", - "zh/guides/pricing/similarweb", *(path.relative_to(ROOT).with_suffix("").as_posix() for path in endpoint_pages), ] config = { @@ -62,7 +56,7 @@ def build_fixture(fixture_root: Path) -> int: "navigation": { "groups": [ { - "group": "SimilarWeb pricing", + "group": "Paid API approval and SimilarWeb endpoints", "pages": pages, } ] diff --git a/zh/agent-quickstart.mdx b/zh/agent-quickstart.mdx index eab1d5d1..e584013d 100644 --- a/zh/agent-quickstart.mdx +++ b/zh/agent-quickstart.mdx @@ -10,26 +10,27 @@ description: >- 目标:让 Agent 走到**最小且可验证**的下一步,而不是一次性加载完整文档索引。 -## 重要:SimilarWeb 先批准后执行合同 + +## 重要:付费和高成本 API 的先批准后执行合同 -该合同适用于每一个 SimilarWeb **数据** endpoint,无论它是直接通过 `/apis/v1/similarweb/...` 调用,还是通过 SimilarWeb MCP 数据工具调用。这是一条安全边界,不是价格发现流程。 +该合同适用于每一个付费、动态计价或可能高成本的 API endpoint,无论它是直接调用、通过 Agent Skill,还是通过 MCP 数据工具调用。这是一条安全边界,不是价格发现流程。 ```xml - + ``` -匹配 endpoint 的 [`x-aisa-pricing`](https://aisa.one/openapi.yaml) 元数据和 [SimilarWeb 价格与成本控制](/zh/guides/pricing/similarweb) 是公开计价的唯一来源;它们提供公式和已记录的成本暴露,不会形成报价 API,也不构成数据调用授权。 +**典型场景 — SimilarWeb:** SimilarWeb 是动态计价、可能高成本的数据 API。请读取匹配 endpoint 的 [`x-aisa-pricing`](https://aisa.one/openapi.yaml) 元数据;只有请求维度可界定时才计算成本,并在数据调用前取得明确批准。元数据提供公式和已记录的成本暴露,不会形成报价 API,也不构成数据调用授权。 ## 最小设置事实 diff --git a/zh/evaluate/pricing.mdx b/zh/evaluate/pricing.mdx index d13b5ccb..c8104b15 100644 --- a/zh/evaluate/pricing.mdx +++ b/zh/evaluate/pricing.mdx @@ -11,7 +11,7 @@ AIsa 对模型推理和计费型 API 能力采用按量计费。具体价格取 - [AI 模型价格](/zh/guides/pricing/ai-model-pricing-llm-inference):模型计费说明。 - [按次调用 API 价格](/zh/guides/pricing/per-call-api-pricing):API 计费说明。 -- [SimilarWeb 价格与成本控制](/zh/guides/pricing/similarweb):SimilarWeb 的公式化端点价格。 +- 匹配的 SimilarWeb endpoint 文档及其 `x-aisa-pricing` 元数据:SimilarWeb 的公式化端点价格。 - [钱包与支付](/zh/guides/pricing/wallet):充值和余额行为。 - [用量日志](/zh/guides/dashboard/usage-logs):账户的实际用量。 - 实时模型目录或具体 API 页面:当前能力的上下文信息。 @@ -58,7 +58,7 @@ AIsa 对模型推理和计费型 API 能力采用按量计费。具体价格取 ## 上线前的验证 -- 对 SimilarWeb,不得通过 SimilarWeb 请求发现价格或验证配置。必须先展示精确 scope、公式和已记录的最大上限,再取得明确批准;如果没有已记录的最大上限,不得按先批准后执行合同调用该端点。 +- 对任何付费或可能高成本的 API,不得通过请求发现价格或验证配置。必须先展示精确 scope、公式或价格规则和已记录的最大上限,再取得明确批准。SimilarWeb 是动态成本的典型场景;如果没有已记录的最大上限,不得按先批准后执行合同调用该端点。 - 确认精确的模型 ID 或 endpoint。 - 查看当前的计价单位。 - 对 SimilarWeb 之外的 API,跑一个有代表性的小请求。 diff --git a/zh/guides/pricing.mdx b/zh/guides/pricing.mdx index e63f1074..f08d7eb9 100644 --- a/zh/guides/pricing.mdx +++ b/zh/guides/pricing.mdx @@ -59,9 +59,9 @@ AI 模型 API 根据 token 用量计费。 如需查看固定按次计费 API 的 endpoint 级价格细节和计费行为,请查看[按次调用 API 价格](/zh/guides/pricing/per-call-api-pricing)。 -### SimilarWeb:公式计费 +### 公式计费的数据 API -SimilarWeb 是付费数据 API,使用 credit 公式。不同端点的费用可能固定、由请求维度决定,或由返回行数决定。发起付费请求前,请阅读 [SimilarWeb 价格与成本控制](/zh/guides/pricing/similarweb);页面会展示当前公式、费用驱动因素、示例和端点级控制方式。 +部分付费数据 API(包括 SimilarWeb)使用 credit 公式,而不是固定的按次价格。发起付费请求前,请阅读匹配 endpoint 文档及其机器可读计价说明;只有请求范围有已记录的最大上限时才计算成本,并取得明确批准。 ## 如何选择正确的计费模型 diff --git a/zh/guides/pricing/per-call-api-pricing.mdx b/zh/guides/pricing/per-call-api-pricing.mdx index 999af958..7b04ebd9 100644 --- a/zh/guides/pricing/per-call-api-pricing.mdx +++ b/zh/guides/pricing/per-call-api-pricing.mdx @@ -7,7 +7,7 @@ excerpt: >- 本页说明 AIsa 中适用的非 LLM API 的固定价格计费模型。 - **重要(IMPORTANT):** 本页不代表所有数据 API 都是固定价格。SimilarWeb 端点可能是固定计费、按返回行数计费,或按请求维度计费。发起付费 SimilarWeb 请求前,请先阅读 [SimilarWeb 价格与成本控制](/zh/guides/pricing/similarweb)。 + **重要(IMPORTANT):** 本页不代表所有数据 API 都是固定价格。部分付费数据 API(包括 SimilarWeb)会按请求维度或返回行数计费。发起付费请求前,请阅读匹配 endpoint 文档和公开计价说明;成本可能较高时必须取得明确批准。 ![AIsa 上的 Tavily Search API 页面,每个 endpoint 都标注了固定的按次调用价格](/images/6bd32ad1-tavily-search-per-call.png) diff --git a/zh/guides/pricing/similarweb.mdx b/zh/guides/pricing/similarweb.mdx deleted file mode 100644 index fed7534c..00000000 --- a/zh/guides/pricing/similarweb.mdx +++ /dev/null @@ -1,256 +0,0 @@ ---- -title: SimilarWeb 价格与成本控制 -excerpt: >- - 从机器可读合同自动生成的 SimilarWeb credit 公式、示例与成本控制说明, - 供人和 Agent 在付费请求前使用。 ---- - -SimilarWeb 是付费数据 API,采用 credit 计费。目录展示值并不总是某次请求的固定、精确报价。 - - - **重要(IMPORTANT,先批准后执行):** SimilarWeb 数据 endpoint 不是价格发现入口。发起任何数据请求前,请使用匹配的 `x-aisa-pricing` 说明明确 scope、公式和已记录的最大成本暴露,再取得用户对该 scope 与上限的明确批准。绝不能发送未经批准的 probe、test 或“先探一下”请求;docs、`/v1/models` 和 MCP discovery 可以作为发现入口。 - - -本页从 [机器可读 OpenAPI](https://aisa.one/openapi.yaml) 中每个端点的 `x-aisa-pricing` 对象自动生成,故意不维护第二份手写费率表。 - -## 如何结算 - -SimilarWeb 使用两阶段 credit 模型:网关可以在 `X-AISA-Estimated-Credits` 中返回预授权估算,然后在 `X-AISA-Accounted-Credits` 和 `X-AISA-Price-USD` 中报告最终结算用量。provider 级 API 合同说明只有成功且非空的响应会计费。这里的公式和示例描述公开计价表,并不是服务端权威的报价接口。 - -不要把目录中的 `pricing.normal = 0` 当成 SimilarWeb 免费调用。 - -## 按请求维度计费 - - -### [Traffic & Engagement](/api-reference/similarweb/get_similarweb-website-traffic-engagement) - -- **计费方式:** 按请求维度 credit 计费。 -- **Credit 费率:** `1 credit / (metric x month)`,每 credit `$0.10`。 -- **公式:** `credits = 1 x metrics x periods`。 -- **费用驱动因素:** `metrics`:请求的指标数量;`periods`:日期范围内的月份数。 -- **当前公开示例:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods.` -- **控制方式:** 费用会随 `metrics`、`start_date`/`end_date` 日期范围 变化;执行前请缩小到必要范围并取得预算确认。 - - -### [Website Ranking](/api-reference/similarweb/get_similarweb-website-ranking) - -- **计费方式:** 按请求维度 credit 计费。 -- **Credit 费率:** `2 credits / (month)`,每 credit `$0.10`。 -- **公式:** `credits = 2 x periods`。 -- **费用驱动因素:** `periods`:日期范围内的月份数。 -- **当前公开示例:** `minimal (1 month) = 2 credits ($0.20); cost grows with periods.` -- **控制方式:** 费用会随 `start_date`/`end_date` 日期范围 变化;执行前请缩小到必要范围并取得预算确认。 - - -### [PPC Spend](/api-reference/similarweb/get_similarweb-website-ppc-spend) - -- **计费方式:** 按请求维度 credit 计费。 -- **Credit 费率:** `1 credit / (month)`,每 credit `$0.10`。 -- **公式:** `credits = 1 x periods`。 -- **费用驱动因素:** `periods`:日期范围内的月份数。 -- **当前公开示例:** `minimal (1 month) = 1 credit ($0.10); cost grows with periods.` -- **控制方式:** 费用会随 `start_date`/`end_date` 日期范围 变化;执行前请缩小到必要范围并取得预算确认。 - - -### [Marketing Channel Sources](/api-reference/similarweb/get_similarweb-website-marketing-channel-sources-legacy) - -- **计费方式:** 按请求维度 credit 计费。 -- **Credit 费率:** `7 credits / (month)`,每 credit `$0.10`。 -- **公式:** `credits = 7 x periods`。 -- **费用驱动因素:** `periods`:日期范围内的月份数。 -- **当前公开示例:** `minimal (1 month) = 7 credits ($0.70); cost grows with periods.` -- **控制方式:** 费用会随 `start_date`/`end_date` 日期范围 变化;执行前请缩小到必要范围并取得预算确认。 - - -### [Deduplicated Audience](/api-reference/similarweb/get_similarweb-website-deduplicated-audience) - -- **计费方式:** 按请求维度 credit 计费。 -- **Credit 费率:** `7 credits / (month)`,每 credit `$0.10`。 -- **公式:** `credits = 7 x periods`。 -- **费用驱动因素:** `periods`:日期范围内的月份数。 -- **当前公开示例:** `minimal (1 month) = 7 credits ($0.70); cost grows with periods.` -- **控制方式:** 费用会随 `start_date`/`end_date` 日期范围 变化;执行前请缩小到必要范围并取得预算确认。 - - -### [Website Traffic Snapshot](/api-reference/similarweb/get_similarweb-website-traffic-snapshot) - -- **计费方式:** 按请求维度 credit 计费。 -- **Credit 费率:** `1 credit / (metric x month)`,每 credit `$0.10`。 -- **公式:** `credits = 1 x metrics x periods`。 -- **费用驱动因素:** `metrics`:请求的指标数量;`periods`:日期范围内的月份数。 -- **Provider 控制的最低示例:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`。对于该端点,`metrics`、`periods` 由 provider 控制,不能由调用方作为请求参数选择。 -- **控制方式:** 公式包含由 provider 控制且不能作为请求参数传入的维度(`metrics`、`periods`)。文档没有公开上限,因此示例只是最低值,不能作为批准上限。在有已记录的最大上限前,不得按先批准后执行合同调用该端点。 - - -### [Website Traffic Trend](/api-reference/similarweb/get_similarweb-website-traffic-trend) - -- **计费方式:** 按请求维度 credit 计费。 -- **Credit 费率:** `1 credit / (metric x month)`,每 credit `$0.10`。 -- **公式:** `credits = 1 x metrics x periods`。 -- **费用驱动因素:** `metrics`:请求的指标数量;`periods`:日期范围内的月份数。 -- **Provider 控制的最低示例:** `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`。对于该端点,`metrics`、`periods` 由 provider 控制,不能由调用方作为请求参数选择。 -- **控制方式:** 公式包含由 provider 控制且不能作为请求参数传入的维度(`metrics`、`periods`)。文档没有公开上限,因此示例只是最低值,不能作为批准上限。在有已记录的最大上限前,不得按先批准后执行合同调用该端点。 - -## 按返回行数计费 - - -### [Top Sites Ranking](/api-reference/similarweb/get_similarweb-website-top-sites-ranking) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `1 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(1 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 1 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [Referrals](/api-reference/similarweb/get_similarweb-website-referrals) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `4 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(4 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 4 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [Ad Networks](/api-reference/similarweb/get_similarweb-website-ad-networks) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `3 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(3 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 3 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [SimilarSites](/api-reference/similarweb/get_similarweb-website-similar-sites) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `5 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(5 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 5 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [Audience Interest](/api-reference/similarweb/get_similarweb-website-audience-interest) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `5 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(5 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 5 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [Audience Overlap](/api-reference/similarweb/get_similarweb-website-audience-overlap) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `2 / row (max 5 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(2 x rows); rows capped at 5`。 -- **费用驱动因素:** `limit`:按返回行数以 2 credit/行累积计费,最多计 5 行。 -- **公开最大成本暴露示例:** `5 rows = 10 credits ($1.00)`。源数据中的 `limit=...` 仅用于说明计量,不是该端点接受的 `limit` 参数。 -- **控制方式:** 该端点按返回行数计费,但没有已记录的 `limit` 参数。不要承诺调用方可通过 `limit` 降低费用;应把公开示例和上限视为一次被接受请求的成本暴露。 - - -### [Popular Pages](/api-reference/similarweb/get_similarweb-website-popular-pages) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `3 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(3 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 3 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [Website Subdomains](/api-reference/similarweb/get_similarweb-website-subdomains) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `2 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(2 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 2 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [Keyword Competitors](/api-reference/similarweb/get_similarweb-search-keyword-competitors) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `0.03 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(0.03 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 0.03 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [Website Keywords](/api-reference/similarweb/get_similarweb-search-website-keywords) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `0.1 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(0.1 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 0.1 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [SERP Players - Clicks over time](/api-reference/similarweb/get_similarweb-search-serp-players-timeseries) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `0.02 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(0.02 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 0.02 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [SERP Players - Aggregated](/api-reference/similarweb/get_similarweb-search-serp-players-aggregated) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `0.07 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(0.07 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 0.07 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [Landing Pages](/api-reference/similarweb/get_similarweb-search-landing-pages) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `0.1 / row (max 20 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(0.1 x rows); rows capped at 20`。 -- **费用驱动因素:** `limit`:按返回行数以 0.1 credit/行累积计费,最多计 20 行。 -- **当前公开示例:** `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)` -- **控制方式:** 返回行数决定 credit 费用;请使用足以回答问题的最小 `limit`。 - - -### [Website Top Geographies](/api-reference/similarweb/get_similarweb-website-top-geographies) - -- **计费方式:** 按返回行数 credit 计费。 -- **Credit 费率:** `3 / row (max 10 rows)`,每 credit `$0.10`。 -- **公式:** `credits = ceil(3 x rows); rows capped at 10`。 -- **费用驱动因素:** `limit`:按返回行数以 3 credit/行累积计费,最多计 10 行。 -- **公开最大成本暴露示例:** `10 rows = 30 credits ($3.00)`。源数据中的 `limit=...` 仅用于说明计量,不是该端点接受的 `limit` 参数。 -- **控制方式:** 该端点按返回行数计费,但没有已记录的 `limit` 参数。不要承诺调用方可通过 `limit` 降低费用;应把公开示例和上限视为一次被接受请求的成本暴露。 - -## 固定每请求计费 - - -### [Demographics](/api-reference/similarweb/get_similarweb-website-demographics) - -- **计费方式:** 固定每请求 credit 计费。 -- **Credit 费率:** `8 credits (fixed)`,每 credit `$0.10`。 -- **公式:** `credits = 8 (fixed per request)`。 -- **费用驱动因素:** `(none)`:每次请求固定 credit 费用。 -- **当前公开示例:** `1 request = 8 credits ($0.80)` -- **控制方式:** 该类请求的公开 credit 费用是固定的。 - - -### [Website Technologies](/api-reference/similarweb/get_similarweb-website-technologies) - -- **计费方式:** 固定每请求 credit 计费。 -- **Credit 费率:** `10 credits (fixed)`,每 credit `$0.10`。 -- **公式:** `credits = 10 (fixed per request)`。 -- **费用驱动因素:** `(none)`:每次请求固定 credit 费用。 -- **当前公开示例:** `1 request = 10 credits ($1.00)` -- **控制方式:** 该类请求的公开 credit 费用是固定的。 From f1f5e367a45b7f570624835179642ec7a4cc256b Mon Sep 17 00:00:00 2001 From: idan Date: Wed, 2 Sep 2026 14:33:26 +0800 Subject: [PATCH 6/8] docs: minimize paid API approval guidance --- .github/workflows/sync-openapi.yml | 3 - .../workflows/validate-similarweb-pricing.yml | 68 --- README.md | 10 +- agent-quickstart.mdx | 36 +- evaluate/pricing.mdx | 4 +- guides/pricing.mdx | 4 +- llms.txt | 5 +- openapi/similarweb.json | 575 +----------------- scripts/check_similarweb_pricing.py | 147 ----- scripts/generate_similarweb_pricing_docs.py | 431 ++----------- scripts/validate_similarweb_mintlify.py | 96 --- zh/agent-quickstart.mdx | 24 +- zh/evaluate/pricing.mdx | 4 +- zh/guides/pricing.mdx | 4 +- 14 files changed, 116 insertions(+), 1295 deletions(-) delete mode 100644 .github/workflows/validate-similarweb-pricing.yml delete mode 100644 scripts/check_similarweb_pricing.py delete mode 100644 scripts/validate_similarweb_mintlify.py diff --git a/.github/workflows/sync-openapi.yml b/.github/workflows/sync-openapi.yml index da7fad19..3c8f3db9 100644 --- a/.github/workflows/sync-openapi.yml +++ b/.github/workflows/sync-openapi.yml @@ -91,9 +91,6 @@ jobs: sys.exit(1) " - - name: Verify SimilarWeb pricing contract - run: python scripts/check_similarweb_pricing.py --generated /tmp/openapi.yaml - # ── 4. Commit spec back to this repo (public download URL) ───── - name: Copy spec to docs repo root run: cp /tmp/openapi.yaml openapi.yaml diff --git a/.github/workflows/validate-similarweb-pricing.yml b/.github/workflows/validate-similarweb-pricing.yml deleted file mode 100644 index 12ee0842..00000000 --- a/.github/workflows/validate-similarweb-pricing.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: Validate SimilarWeb Pricing Docs - -on: - pull_request: - paths: - - ".github/workflows/validate-similarweb-pricing.yml" - - ".github/workflows/sync-openapi.yml" - - "docs.json" - - "llms.txt" - - "agent-quickstart.mdx" - - "zh/agent-quickstart.mdx" - - "openapi/**" - - "api-reference/similarweb/**" - - "zh/api-reference/similarweb/**" - - "guides/pricing.mdx" - - "guides/pricing/**" - - "zh/guides/pricing.mdx" - - "zh/guides/pricing/**" - - "evaluate/pricing.mdx" - - "zh/evaluate/pricing.mdx" - - "scripts/check_similarweb_pricing.py" - - "scripts/consolidate_openapi.py" - - "scripts/generate_similarweb_pricing_docs.py" - - "scripts/validate_similarweb_mintlify.py" - workflow_dispatch: - -permissions: - contents: read - -jobs: - validate: - name: Check generated pricing surfaces - runs-on: ubuntu-latest - timeout-minutes: 5 - - steps: - - name: Checkout docs repository - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.12" - - - name: Set up Node.js for Mintlify validation - uses: actions/setup-node@v4 - with: - node-version: "20.17" - - - name: Install dependencies - run: pip install pyyaml - - - name: Check checked-in pricing surfaces - run: python scripts/generate_similarweb_pricing_docs.py --check - - - name: Consolidate OpenAPI source - run: python scripts/consolidate_openapi.py --output /tmp/openapi.yaml - - - name: Check generated OpenAPI and discovery paths - run: python scripts/check_similarweb_pricing.py --generated /tmp/openapi.yaml - - - name: Validate generated docs and OpenAPI with Mintlify - run: python scripts/validate_similarweb_mintlify.py - - - name: Check patch whitespace - run: git diff --check "origin/${{ github.base_ref }}...HEAD" diff --git a/README.md b/README.md index 7b521272..dcdfea3e 100644 --- a/README.md +++ b/README.md @@ -81,17 +81,15 @@ python3 scripts/consolidate_openapi.py --output /tmp/aisa-openapi.yaml `openapi/*.json` files are the source of truth. The root `openapi.yaml` is generated by the sync workflow and should not be edited directly. -When changing SimilarWeb's `x-aisa-pricing` metadata, regenerate the human -pricing disclosures and guides before opening a pull request: +When changing SimilarWeb's `x-aisa-pricing` metadata, refresh its endpoint +price notices before opening a pull request: ```bash python3 scripts/generate_similarweb_pricing_docs.py --write -python3 scripts/generate_similarweb_pricing_docs.py --check ``` -The generator deliberately derives the endpoint copy from the OpenAPI metadata -so no second hand-authored rate schedule can drift from the agent-facing -contract. +The notices are derived from the OpenAPI metadata, so no hand-authored rate +schedule can drift from the agent-facing endpoint page. After the generated `openapi.yaml` commit is pushed to `main`, the workflow sends a `docs_openapi_updated` repository dispatch to diff --git a/agent-quickstart.mdx b/agent-quickstart.mdx index cdd739e6..d841ccdb 100644 --- a/agent-quickstart.mdx +++ b/agent-quickstart.mdx @@ -13,38 +13,30 @@ Goal: get the agent to the smallest verifiable next step without loading broad d ## IMPORTANT: Paid and high-cost API approval-first contract -This contract applies to every paid, dynamically priced, or potentially high-cost API endpoint, whether invoked directly, through an Agent Skill, or through an MCP data tool. It is a safety boundary, not a price discovery workflow. +This contract applies to every paid, dynamically priced, or potentially high-cost API endpoint, whether invoked directly, through an Agent Skill, or through an MCP data tool. ```xml ``` -**Classic example — SimilarWeb:** SimilarWeb is a dynamic, potentially high-cost data API. Read the matching endpoint's [`x-aisa-pricing`](https://aisa.one/openapi.yaml) metadata, calculate the chosen request's cost only when its dimensions are bounded, and obtain explicit approval before the data call. The metadata provides a formula and documented exposure; it does not create a quote API or authorize a request. +**Classic example — SimilarWeb:** read the matching endpoint's [`x-aisa-pricing`](https://aisa.one/openapi.yaml) metadata, calculate only a bounded request, and obtain explicit approval before the data call. ## Minimal setup facts diff --git a/evaluate/pricing.mdx b/evaluate/pricing.mdx index 82c9606f..cea524d2 100644 --- a/evaluate/pricing.mdx +++ b/evaluate/pricing.mdx @@ -11,7 +11,6 @@ Use current pricing sources for final decisions. - [AI Model Pricing](/guides/pricing/ai-model-pricing-llm-inference) for model-pricing guidance. - [Per-call API Pricing](/guides/pricing/per-call-api-pricing) for API billing guidance. -- The matching SimilarWeb endpoint documentation and its `x-aisa-pricing` metadata for SimilarWeb's formula-based endpoint pricing. - [Wallet and Payments](/guides/pricing/wallet) for funding and balance behavior. - [Usage Logs](/guides/dashboard/usage-logs) for observed account usage. - The live model catalog or exact API page for current capability context. @@ -58,10 +57,9 @@ A direct provider can be the simpler option for a stable, single-provider worklo ## Verify before production -- For any paid or potentially high-cost API, do not run a request to discover price or validate setup. First present the exact scope, formula or price rule, and documented maximum, then obtain explicit approval. SimilarWeb is a classic dynamic-cost example; if it has no documented upper bound, do not execute that endpoint under the approval-first contract. - Confirm the exact model ID or endpoint. - Check current price units. -- For APIs other than SimilarWeb, run a small representative request. +- Run a small representative request. - Inspect the usage record. - Measure the complete workflow, not only one call. - Add budget alerts before scaling traffic. diff --git a/guides/pricing.mdx b/guides/pricing.mdx index 828d201c..7e68b8c7 100644 --- a/guides/pricing.mdx +++ b/guides/pricing.mdx @@ -60,9 +60,7 @@ This pricing model applies to APIs such as: For endpoint-level pricing details and billing behavior, see [Per-Call API Pricing](/guides/pricing/per-call-api-pricing). -### Formula-priced data APIs - -Some paid data APIs, including SimilarWeb, use a credit formula rather than a fixed per-call price. Read the matching endpoint documentation and its machine-readable pricing declaration before a paid request; calculate the selected scope only when it has a documented maximum, then obtain explicit approval. +Some paid data APIs, including SimilarWeb, use a credit formula rather than a fixed per-call price. Read the matching endpoint documentation and pricing declaration before a paid request; if a maximum is not documented, do not execute it under the approval-first contract. ## Choosing the Correct Pricing Model diff --git a/llms.txt b/llms.txt index d504f0e0..4fdf408e 100644 --- a/llms.txt +++ b/llms.txt @@ -14,7 +14,7 @@ Use this index to choose the smallest relevant documentation set. For product di - [Rate Limits](https://aisa.one/docs/api-reference/rate-limits): limits and relevant headers. ## Navigate by Goal @@ -56,7 +56,7 @@ For any paid, dynamically priced, or potentially high-cost API endpoint, first r - [Twitter API](https://aisa.one/docs/api-reference/twitter/get_twitter-user-info): X/Twitter read and authenticated write routes. - [Scholar API](https://aisa.one/docs/api-reference/scholar/post_scholar-search-scholar): academic and mixed-source search. - [Prediction Market API](https://aisa.one/docs/api-reference/prediction-market/get_polymarket-events): Polymarket and Kalshi data. -- [SimilarWeb API](https://aisa.one/docs/api-reference/similarweb/get_similarweb-website-similar-sites): digital-intelligence data; read the matching endpoint's `x-aisa-pricing` metadata before a paid call. +- [SimilarWeb API](https://aisa.one/docs/api-reference/similarweb/get_similarweb-website-similar-sites): digital-intelligence data. ## Machine Discovery @@ -73,4 +73,3 @@ For any paid, dynamically priced, or potentially high-cost API endpoint, first r - Treat search results as discovery, fetched pages as evidence, and generated text as synthesis. - Separate read operations from writes and payments; verify authorization before side effects. - Check live availability, status, pricing, and authentication before relying on a capability. -- For SimilarWeb, follow the paid-API approval-first contract above: load the matching endpoint and `x-aisa-pricing` metadata, state the formula and documented maximum exposure, then request explicit approval before the data call. Do not treat a catalog display value as a request-specific quote. diff --git a/openapi/similarweb.json b/openapi/similarweb.json index 176d5d09..90e12c86 100644 --- a/openapi/similarweb.json +++ b/openapi/similarweb.json @@ -38,7 +38,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Traffic & Engagement", - "description": "Traffic & Engagement. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Current schedule example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods.`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Cost varies with `metrics`, the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Traffic & Engagement. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_traffic_engagement", "parameters": [ { @@ -228,29 +228,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -274,7 +251,7 @@ "example": "minimal (1 month) = 2 credits ($0.20); cost grows with periods." }, "summary": "Website Ranking", - "description": "Website Ranking. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 credits / (month)` at `$0.10` per credit. Formula: `credits = 2 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 2 credits ($0.20); cost grows with periods.`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Website Ranking. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `2 credits / (month)` at `$0.10` per credit. Formula: `credits = 2 x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_ranking", "parameters": [ { @@ -418,29 +395,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -464,7 +418,7 @@ "example": "minimal (1 month) = 1 credit ($0.10); cost grows with periods." }, "summary": "PPC Spend", - "description": "PPC Spend. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (month)` at `$0.10` per credit. Formula: `credits = 1 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 1 credit ($0.10); cost grows with periods.`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "PPC Spend. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (month)` at `$0.10` per credit. Formula: `credits = 1 x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_ppc_spend", "parameters": [ { @@ -602,29 +556,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -648,7 +579,7 @@ "example": "20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)" }, "summary": "Top Sites Ranking", - "description": "Top Sites Ranking. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Top Sites Ranking. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(1 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_top_sites_ranking", "parameters": [ { @@ -751,29 +682,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -797,7 +705,7 @@ "example": "minimal (1 month) = 7 credits ($0.70); cost grows with periods." }, "summary": "Marketing Channel Sources", - "description": "Marketing Channel Sources. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 7 credits ($0.70); cost grows with periods.`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Marketing Channel Sources. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_marketing_channel_sources_legacy", "parameters": [ { @@ -949,29 +857,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -995,7 +880,7 @@ "example": "20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)" }, "summary": "Referrals", - "description": "Referrals. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `4 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(4 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 4 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Referrals. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `4 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(4 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_referrals", "parameters": [ { @@ -1169,29 +1054,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -1215,7 +1077,7 @@ "example": "20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)" }, "summary": "Ad Networks", - "description": "Ad Networks. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Ad Networks. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_ad_networks", "parameters": [ { @@ -1390,29 +1252,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -1436,7 +1275,7 @@ "example": "20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)" }, "summary": "SimilarSites", - "description": "SimilarSites. Response follows the SimilarWeb v5 envelope (meta + data). Date window (upstream SimilarWeb constraint): start_date and end_date must span EXACTLY 3 consecutive months — a 1- or 2-month span is rejected with upstream error 120 ('must span exactly 3 month(s)'). That span must also be SimilarWeb's most recent supported window, which advances forward each month; an older or out-of-range span is rejected with error 101 ('Dates not in range'). In practice, request the three most recent completed months (e.g. if the latest published month is 2026-07, use start_date=2026-05 and end_date=2026-07). To read the exact currently-supported range, call SimilarWeb's /describe endpoint for this API.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "SimilarSites. Response follows the SimilarWeb v5 envelope (meta + data). Date window (upstream SimilarWeb constraint): start_date and end_date must span EXACTLY 3 consecutive months — a 1- or 2-month span is rejected with upstream error 120 ('must span exactly 3 month(s)'). That span must also be SimilarWeb's most recent supported window, which advances forward each month; an older or out-of-range span is rejected with error 101 ('Dates not in range'). In practice, request the three most recent completed months (e.g. if the latest published month is 2026-07, use start_date=2026-05 and end_date=2026-07). To read the exact currently-supported range, call SimilarWeb's /describe endpoint for this API.\n\n**Pricing (from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_similar_sites", "parameters": [ { @@ -1616,29 +1455,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -1662,7 +1478,7 @@ "example": "1 request = 8 credits ($0.80)" }, "summary": "Demographics", - "description": "Demographics. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must fall in the SAME month (exactly one monthly bucket).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `8 credits (fixed)` at `$0.10` per credit. Formula: `credits = 8 (fixed per request)`. Cost drivers: `(none)`: flat per-request credit charge. Current schedule example: `1 request = 8 credits ($0.80)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. The published credit charge is fixed for this request type. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Demographics. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must fall in the SAME month (exactly one monthly bucket).\n\n**Pricing (from `x-aisa-pricing`):** `8 credits (fixed)` at `$0.10` per credit. Formula: `credits = 8 (fixed per request)`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_demographics", "parameters": [ { @@ -1834,29 +1650,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -1880,7 +1673,7 @@ "example": "minimal (1 month) = 7 credits ($0.70); cost grows with periods." }, "summary": "Deduplicated Audience", - "description": "Deduplicated Audience. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Cost drivers: `periods`: number of months in the date window. Current schedule example: `minimal (1 month) = 7 credits ($0.70); cost grows with periods.`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Cost varies with the `start_date`/`end_date` range; set the smallest required scope and obtain a budget decision before execution. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Deduplicated Audience. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_deduplicated_audience", "parameters": [ { @@ -2044,29 +1837,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -2090,7 +1860,7 @@ "example": "20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)" }, "summary": "Audience Interest", - "description": "Audience Interest. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 5 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Audience Interest. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_audience_interest", "parameters": [ { @@ -2274,29 +2044,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -2320,7 +2067,7 @@ "example": "5 rows = 10 credits ($1.00); limit=5 = 10 credits ($1.00)" }, "summary": "Audience Overlap", - "description": "Audience Overlap. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 / row (max 5 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 5`. Cost drivers: `limit`: charge scales with rows returned at 2 credit/row; at most 5 rows are billed. Published maximum-exposure example: `5 rows = 10 credits ($1.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`.\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Audience Overlap. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n**Pricing (from `x-aisa-pricing`):** `2 / row (max 5 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 5`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_audience_overlap", "parameters": [ { @@ -2435,29 +2182,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -2481,7 +2205,7 @@ "example": "1 request = 10 credits ($1.00)" }, "summary": "Website Technologies", - "description": "Website Technologies. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must be the SAME month, and that month must be the latest available data month — a single monthly bucket that advances as SimilarWeb refreshes its data, and which may differ by country. Supplying any other month returns SimilarWeb error_code 101 (\"Dates not in range\"); the error message states the currently-allowed range.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `10 credits (fixed)` at `$0.10` per credit. Formula: `credits = 10 (fixed per request)`. Cost drivers: `(none)`: flat per-request credit charge. Current schedule example: `1 request = 10 credits ($1.00)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. The published credit charge is fixed for this request type. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Website Technologies. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must be the SAME month, and that month must be the latest available data month — a single monthly bucket that advances as SimilarWeb refreshes its data, and which may differ by country. Supplying any other month returns SimilarWeb error_code 101 (\"Dates not in range\"); the error message states the currently-allowed range.\n\n**Pricing (from `x-aisa-pricing`):** `10 credits (fixed)` at `$0.10` per credit. Formula: `credits = 10 (fixed per request)`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_technologies", "parameters": [ { @@ -2664,29 +2388,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -2710,7 +2411,7 @@ "example": "20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)" }, "summary": "Popular Pages", - "description": "Popular Pages. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Popular Pages. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n**Pricing (from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_popular_pages", "parameters": [ { @@ -2885,29 +2586,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -2931,7 +2609,7 @@ "example": "20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)" }, "summary": "Website Subdomains", - "description": "Website Subdomains. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `2 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 2 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Website Subdomains. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `2 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_subdomains", "parameters": [ { @@ -3096,29 +2774,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -3142,7 +2797,7 @@ "example": "20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)" }, "summary": "Keyword Competitors", - "description": "Keyword Competitors. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.03 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.03 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.03 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Keyword Competitors. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.03 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.03 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_keyword_competitors", "parameters": [ { @@ -3314,29 +2969,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -3360,7 +2992,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "Website Keywords", - "description": "Website Keywords. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 3 monthly buckets. Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Website Keywords. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 3 monthly buckets. Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n**Pricing (from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_keywords", "parameters": [ { @@ -3577,29 +3209,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -3623,7 +3232,7 @@ "example": "20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)" }, "summary": "SERP Players - Clicks over time", - "description": "SERP Players - Clicks over time. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.02 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.02 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.02 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "SERP Players - Clicks over time. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.02 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.02 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_serp_players_timeseries", "parameters": [ { @@ -3761,29 +3370,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -3807,7 +3393,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "SERP Players - Aggregated", - "description": "SERP Players - Aggregated. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.07 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.07 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.07 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "SERP Players - Aggregated. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.07 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.07 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_serp_players_aggregated", "parameters": [ { @@ -3975,29 +3561,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -4021,7 +3584,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "Landing Pages", - "description": "Landing Pages. Response follows the SimilarWeb v5 envelope (meta + data).\n\n\n**Pricing (generated from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Cost drivers: `limit`: charge scales with rows returned at 0.1 credit/row; at most 20 rows are billed. Current schedule example: `20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)`\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. Use the smallest meaningful `limit`; returned rows drive the credit cost. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Landing Pages. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_landing_pages", "parameters": [ { @@ -4222,29 +3785,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -4272,7 +3812,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Website Traffic Snapshot", - "description": "Latest-month traffic snapshot for a domain: visits plus core engagement metrics (average visit duration, bounce rate, pages per visit) in a single object. The most recent available month is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled lower-bound example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Latest-month traffic snapshot for a domain: visits plus core engagement metrics (average visit duration, bounce rate, pages per visit) in a single object. The most recent available month is selected automatically and echoed in meta.start_date / meta.end_date.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_website_traffic_snapshot", "parameters": [ { @@ -4385,29 +3925,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -4435,7 +3952,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Website Traffic Trend", - "description": "Monthly traffic time series for a domain over the recent available window (data.points, one entry per month). The window is selected automatically and echoed in meta.start_date / meta.end_date.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Cost drivers: `metrics`: number of metrics requested; `periods`: number of months in the date window. Provider-controlled lower-bound example: `minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods`. `metrics`, `periods` are provider-controlled for this endpoint, not caller-selectable request parameters.\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. The formula includes provider-controlled dimensions (`metrics`, `periods`) that are not accepted request parameters. The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. Do not execute this operation under the approval-first contract until a documented maximum is available. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Monthly traffic time series for a domain over the recent available window (data.points, one entry per month). The window is selected automatically and echoed in meta.start_date / meta.end_date.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_website_traffic_trend", "parameters": [ { @@ -4587,29 +4104,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } @@ -4633,7 +4127,7 @@ "example": "10 rows = 30 credits ($3.00); limit=5 = 15 credits ($1.50)" }, "summary": "Website Top Geographies", - "description": "Top countries by share of a domain's traffic for the latest available month (data.countries, up to 10 rows with country_code, country_name, share and visits). Geography coverage is worldwide (ww) and fixed: a country parameter is not accepted for this endpoint.\n\n\n**Pricing (generated from `x-aisa-pricing`):** `3 / row (max 10 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 10`. Cost drivers: `limit`: charge scales with rows returned at 3 credit/row; at most 10 rows are billed. Published maximum-exposure example: `10 rows = 30 credits ($3.00)`. The source's `limit=...` text is a metering illustration only; this endpoint does not accept `limit`.\n\n**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce its cost with `limit`; use the documented example and cap as the exposure of one accepted request. Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval before a paid request.\n\n", + "description": "Top countries by share of a domain's traffic for the latest available month (data.countries, up to 10 rows with country_code, country_name, share and visits). Geography coverage is worldwide (ww) and fixed: a country parameter is not accepted for this endpoint.\n\n**Pricing (from `x-aisa-pricing`):** `3 / row (max 10 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 10`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", "operationId": "get_similarweb_website_top_geographies", "parameters": [ { @@ -4797,29 +4291,6 @@ } } } - }, - "headers": { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": { - "type": "number", - "format": "float" - } - } } } } diff --git a/scripts/check_similarweb_pricing.py b/scripts/check_similarweb_pricing.py deleted file mode 100644 index a0ef265a..00000000 --- a/scripts/check_similarweb_pricing.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env python3 -"""Validate that SimilarWeb's human and machine pricing surfaces stay aligned.""" - -from __future__ import annotations - -import argparse -from pathlib import Path -from typing import Any - -import yaml - -from generate_similarweb_pricing_docs import ( - EXPECTED_OPERATION_IDS, - ROOT, - SETTLEMENT_RESPONSE_HEADERS, - SOURCE_PATH, - check_outputs, - category, - collect_operations, - expected_outputs, - load_source, - provider_controlled_drivers, -) - - -LLMS_PATH = ROOT / "llms.txt" -AGENT_QUICKSTART_PATH = ROOT / "agent-quickstart.mdx" -ZH_AGENT_QUICKSTART_PATH = ROOT / "zh" / "agent-quickstart.mdx" -PRICING_OVERVIEW_PATH = ROOT / "guides" / "pricing.mdx" -PER_CALL_PATH = ROOT / "guides" / "pricing" / "per-call-api-pricing.mdx" -ZH_PRICING_OVERVIEW_PATH = ROOT / "zh" / "guides" / "pricing.mdx" -ZH_PER_CALL_PATH = ROOT / "zh" / "guides" / "pricing" / "per-call-api-pricing.mdx" -EVALUATE_PRICING_PATH = ROOT / "evaluate" / "pricing.mdx" -ZH_EVALUATE_PRICING_PATH = ROOT / "zh" / "evaluate" / "pricing.mdx" - - -def fail(message: str) -> None: - raise SystemExit(f"pricing contract check failed: {message}") - - -def check_checked_in_surfaces(source: dict[str, Any]) -> None: - stale = check_outputs(expected_outputs(source)) - if stale: - paths = ", ".join(str(path.relative_to(ROOT)) for path in stale) - fail(f"generated surfaces are stale: {paths}; run generate_similarweb_pricing_docs.py --write") - - operations = collect_operations(source) - for operation in operations: - endpoint = ROOT / "api-reference" / "similarweb" / f"{operation.endpoint_slug}.mdx" - if not endpoint.exists(): - fail(f"{operation.operation_id} has no endpoint documentation page") - source_operation = source["paths"][operation.path][operation.method] - description = source_operation["description"] - response = source_operation.get("responses", {}).get("200") - if not isinstance(response, dict) or response.get("headers") != SETTLEMENT_RESPONSE_HEADERS: - fail(f"{operation.operation_id} lacks the generated settlement response headers") - if "/agent-quickstart#paid-api-approval-first" not in description: - fail(f"{operation.operation_id} does not route agents to the paid-API approval-first contract") - uncontrolled = provider_controlled_drivers(operation) - if category(operation) == "rows" and uncontrolled: - if "does not accept `limit`" not in description: - fail(f"{operation.operation_id} does not disclose that limit is unavailable") - if "; limit=" in description: - fail(f"{operation.operation_id} renders a non-callable limit example as request syntax") - if category(operation) == "dimensions" and uncontrolled and not operation.parameter_names.intersection({"metrics", "start_date", "end_date"}): - if "provider-controlled dimensions" not in description: - fail(f"{operation.operation_id} does not disclose provider-controlled pricing dimensions") - if "documentation does not publish an upper bound" not in description or "not an approval cap" not in description: - fail(f"{operation.operation_id} presents a provider-controlled lower bound as an approval cap") - - llms = LLMS_PATH.read_text(encoding="utf-8") - for marker in ("", "explicit approval", "price discovery", "x-aisa-pricing", "/v1/models", "MCP discovery", "SimilarWeb is a classic"): - if marker not in llms: - fail(f"llms.txt lacks paid-API approval-first marker: {marker}") - for path, markers in ( - (AGENT_QUICKSTART_PATH, ("", "explicit approval", "price discovery", "published pricing source", "/v1/models", "MCP discovery", "Classic example — SimilarWeb")), - (ZH_AGENT_QUICKSTART_PATH, ("", "明确批准", "价格发现", "公开计价来源", "/v1/models", "MCP discovery", "典型场景 — SimilarWeb")), - ): - content = path.read_text(encoding="utf-8") - for marker in markers: - if marker not in content: - fail(f"{path.relative_to(ROOT)} lacks SimilarWeb approval-first marker: {marker}") - similar_sites = next(operation for operation in operations if operation.operation_id == "get_similarweb_similar_sites") - endpoint_url = f"https://aisa.one/docs/api-reference/similarweb/{similar_sites.endpoint_slug}" - if endpoint_url not in llms: - fail("llms.txt SimilarWeb API family link does not resolve to the SimilarSites endpoint page") - - english_overview = PRICING_OVERVIEW_PATH.read_text(encoding="utf-8") - chinese_overview = ZH_PRICING_OVERVIEW_PATH.read_text(encoding="utf-8") - if "All non-LLM APIs use a fixed per-request billing model." in english_overview: - fail("English pricing overview still classifies every non-LLM API as fixed-price") - if "所有非 LLM API 使用固定的按请求计费模型。" in chinese_overview: - fail("Chinese pricing overview still classifies every non-LLM API as fixed-price") - - for path in (PRICING_OVERVIEW_PATH, PER_CALL_PATH, ZH_PRICING_OVERVIEW_PATH, ZH_PER_CALL_PATH): - content = path.read_text(encoding="utf-8").lower() - if "similarweb" not in content or "endpoint" not in content: - fail(f"{path.relative_to(ROOT)} does not route formula-priced APIs to endpoint documentation") - - for path, markers in ( - (EVALUATE_PRICING_PATH, ("any paid or potentially high-cost API", "explicit approval", "SimilarWeb is a classic")), - (ZH_EVALUATE_PRICING_PATH, ("任何付费或可能高成本的 API", "明确批准", "SimilarWeb 是动态成本的典型场景")), - ): - content = path.read_text(encoding="utf-8") - for marker in markers: - if marker not in content: - fail(f"{path.relative_to(ROOT)} lacks the SimilarWeb no-probe exception: {marker}") - - -def check_consolidated_openapi(source: dict[str, Any], generated_path: Path) -> None: - with generated_path.open(encoding="utf-8") as stream: - generated = yaml.safe_load(stream) - if not isinstance(generated, dict) or not isinstance(generated.get("paths"), dict): - fail("generated OpenAPI has no paths object") - - for operation in collect_operations(source): - expected = operation.pricing - generated_operation = generated["paths"].get(operation.path, {}).get(operation.method, {}) - actual = generated_operation.get("x-aisa-pricing") - if actual != expected: - fail(f"generated OpenAPI did not preserve x-aisa-pricing for {operation.path}") - response = generated_operation.get("responses", {}).get("200") - if not isinstance(response, dict) or response.get("headers") != SETTLEMENT_RESPONSE_HEADERS: - fail(f"generated OpenAPI did not preserve settlement headers for {operation.path}") - - -def main() -> None: - parser = argparse.ArgumentParser() - parser.add_argument( - "--generated", - type=Path, - help="optional consolidated OpenAPI YAML to compare with the source", - ) - args = parser.parse_args() - - source = load_source() - operations = collect_operations(source) - if len(operations) != len(EXPECTED_OPERATION_IDS): - fail("unexpected SimilarWeb operation inventory") - check_checked_in_surfaces(source) - if args.generated: - check_consolidated_openapi(source, args.generated) - print(f"pricing contract check passed: {len(operations)} SimilarWeb operations") - - -if __name__ == "__main__": - main() diff --git a/scripts/generate_similarweb_pricing_docs.py b/scripts/generate_similarweb_pricing_docs.py index df14fbb2..ebb98163 100644 --- a/scripts/generate_similarweb_pricing_docs.py +++ b/scripts/generate_similarweb_pricing_docs.py @@ -1,421 +1,110 @@ #!/usr/bin/env python3 -"""Generate SimilarWeb's human-readable pricing surfaces from OpenAPI metadata. - -`x-aisa-pricing` is the only source of monetary facts. This script renders the -English and Chinese pricing guides plus the pricing disclosure shown on each -SimilarWeb endpoint page. Run with ``--write`` when the metadata changes and -``--check`` in CI to prevent a hand-edited guide or endpoint description from -drifting from the machine-readable contract. -""" +"""Derive concise SimilarWeb endpoint price notices from x-aisa-pricing.""" from __future__ import annotations import argparse -import copy import json import re -from dataclasses import dataclass -from decimal import Decimal, InvalidOperation from pathlib import Path from typing import Any -ROOT = Path(__file__).resolve().parents[1] +ROOT = Path(__file__).resolve().parent.parent SOURCE_PATH = ROOT / "openapi" / "similarweb.json" -API_REFERENCE_DIR = ROOT / "api-reference" / "similarweb" - -EXPECTED_OPERATION_IDS = frozenset( - { - "get_similarweb_traffic_engagement", - "get_similarweb_ranking", - "get_similarweb_ppc_spend", - "get_similarweb_top_sites_ranking", - "get_similarweb_marketing_channel_sources_legacy", - "get_similarweb_referrals", - "get_similarweb_ad_networks", - "get_similarweb_similar_sites", - "get_similarweb_demographics", - "get_similarweb_deduplicated_audience", - "get_similarweb_audience_interest", - "get_similarweb_audience_overlap", - "get_similarweb_technologies", - "get_similarweb_popular_pages", - "get_similarweb_subdomains", - "get_similarweb_keyword_competitors", - "get_similarweb_keywords", - "get_similarweb_serp_players_timeseries", - "get_similarweb_serp_players_aggregated", - "get_similarweb_landing_pages", - "get_similarweb_website_traffic_snapshot", - "get_similarweb_website_traffic_trend", - "get_similarweb_website_top_geographies", - } -) - -DISCLOSURE_START = "" -DISCLOSURE_END = "" -DISCLOSURE_PATTERN = re.compile( - rf"\n*{re.escape(DISCLOSURE_START)}.*?{re.escape(DISCLOSURE_END)}\n*", +HTTP_METHODS = {"delete", "get", "head", "options", "patch", "post", "put", "trace"} +LEGACY_DISCLOSURE = re.compile( + r"\n*.*?" + r"\s*", re.DOTALL, ) -OPENAPI_REFERENCE_PATTERN = re.compile( - r'^openapi:\s+"openapi/similarweb\.json (?P[A-Z]+) (?P[^"]+)"$', - re.MULTILINE, +NOTICE = re.compile( + r"\n{2}\*\*Pricing \(from `x-aisa-pricing`\):\*\*.*?(?=\n{2}|\Z)", + re.DOTALL, ) -HTTP_METHODS = frozenset({"get", "put", "post", "delete", "options", "head", "patch", "trace"}) -SETTLEMENT_RESPONSE_HEADERS: dict[str, dict[str, Any]] = { - "X-AISA-Estimated-Credits": { - "description": "Pre-authorization credit estimate for this accepted request. It is an estimate, not a quote or authorization to make a request.", - "schema": {"type": "number", "format": "float"}, - }, - "X-AISA-Accounted-Credits": { - "description": "Credits settled for the completed response. Present only when the gateway records settled usage.", - "schema": {"type": "number", "format": "float"}, - }, - "X-AISA-Price-USD": { - "description": "USD amount settled for the completed response. Present only when the gateway records settled usage.", - "schema": {"type": "number", "format": "float"}, - }, -} -CREDIT_EXAMPLE_RE = re.compile(r"(?P\d+(?:\.\d+)?) credits? \(\$(?P\d+(?:\.\d+)?)\)") - -@dataclass(frozen=True) -class Operation: - """A SimilarWeb operation together with its #92 pricing contract.""" - - path: str - method: str - operation_id: str - endpoint_slug: str - summary: str - pricing: dict[str, Any] - parameter_names: frozenset[str] def fail(message: str) -> None: - raise ValueError(f"SimilarWeb pricing generation failed: {message}") + raise SystemExit(f"SimilarWeb pricing disclosure: {message}") + +def price_usd(value: Any, location: str) -> str: + if not isinstance(value, (int, float)) or isinstance(value, bool) or value < 0: + fail(f"{location} has an invalid credit_price_usd") + return f"${value:.2f}" -def load_source() -> dict[str, Any]: - with SOURCE_PATH.open(encoding="utf-8") as stream: - source = json.load(stream) - if not isinstance(source, dict): - fail("openapi/similarweb.json is not an object") - return source +def required_text(pricing: dict[str, Any], field: str, location: str) -> str: + value = pricing.get(field) + if not isinstance(value, str) or not value.strip(): + fail(f"{location} has no {field}") + return value.strip() -def validate_pricing(path: str, pricing: Any) -> dict[str, Any]: - if not isinstance(pricing, dict): - fail(f"{path} has no x-aisa-pricing object") - required = { - "model", - "currency", - "credit_price_usd", - "credit_formula", - "credit_rate", - "cost_drivers", - "cost_tier", - "example", - } - missing = sorted(required - pricing.keys()) - if missing: - fail(f"{path} is missing pricing keys: {', '.join(missing)}") - if pricing["model"] != "per_credit": - fail(f"{path} has unsupported pricing model {pricing['model']!r}") - if pricing["currency"] != "USD": - fail(f"{path} must use USD") - if not isinstance(pricing["credit_price_usd"], (int, float)) or pricing["credit_price_usd"] <= 0: - fail(f"{path} must have a positive credit_price_usd") - for field in ("credit_formula", "credit_rate", "cost_tier", "example"): - if not isinstance(pricing[field], str) or not pricing[field].strip(): - fail(f"{path} has an empty {field}") - if not isinstance(pricing["cost_drivers"], list) or not pricing["cost_drivers"]: - fail(f"{path} needs at least one cost driver") - for driver in pricing["cost_drivers"]: - if not isinstance(driver, dict): - fail(f"{path} has a non-object cost driver") - for field in ("param", "effect"): - if not isinstance(driver.get(field), str) or not driver[field].strip(): - fail(f"{path} has an invalid cost driver {field}") - examples = list(CREDIT_EXAMPLE_RE.finditer(pricing["example"])) - if not examples: - fail(f"{path} example has no parseable credits-to-USD amount") - credit_price = Decimal(str(pricing["credit_price_usd"])) - for match in examples: - try: - credits = Decimal(match.group("credits")) - documented_usd = Decimal(match.group("usd")) - except InvalidOperation as error: - raise AssertionError("credit example regex must only capture decimals") from error - expected_usd = credits * credit_price - if documented_usd != expected_usd: - fail( - f"{path} example has ${documented_usd} for {credits} credits; " - f"expected ${expected_usd} at ${credit_price} per credit" - ) - return pricing +def notice(pricing: dict[str, Any], location: str) -> str: + return ( + "**Pricing (from `x-aisa-pricing`):** " + f"`{required_text(pricing, 'credit_rate', location)}` at " + f"`{price_usd(pricing.get('credit_price_usd'), location)}` per credit. " + f"Formula: `{required_text(pricing, 'credit_formula', location)}`. " + "Before a paid data call, follow " + "[Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval." + ) -def api_reference_pages() -> dict[tuple[str, str], str]: - pages: dict[tuple[str, str], str] = {} - for page in API_REFERENCE_DIR.glob("*.mdx"): - match = OPENAPI_REFERENCE_PATTERN.search(page.read_text(encoding="utf-8")) - if not match: - continue - path = match.group("path") - method = match.group("method").lower() - key = (path, method) - if key in pages: - fail(f"duplicate endpoint page for {method.upper()} {path}") - pages[key] = page.stem - return pages +def without_prior_notice(description: str) -> str: + return NOTICE.sub("", LEGACY_DISCLOSURE.sub("", description)).rstrip() -def collect_operations(source: dict[str, Any]) -> list[Operation]: +def render(source: dict[str, Any]) -> str: paths = source.get("paths") if not isinstance(paths, dict): - fail("source OpenAPI has no paths object") + fail("OpenAPI source has no paths object") - reference_pages = api_reference_pages() - operations: list[Operation] = [] - seen_ids: set[str] = set() - for path, item in paths.items(): - if not isinstance(item, dict): + operation_count = 0 + for path, path_item in paths.items(): + if not isinstance(path_item, dict): continue - for method, operation in item.items(): + for method, operation in path_item.items(): if method not in HTTP_METHODS: continue if not isinstance(operation, dict): fail(f"{method.upper()} {path} is not an operation object") - if "x-aisa-pricing" not in operation: - fail(f"{method.upper()} {path} has no x-aisa-pricing object") - - operation_id = operation.get("operationId") - summary = operation.get("summary") + pricing = operation.get("x-aisa-pricing") description = operation.get("description") - if not isinstance(operation_id, str) or not operation_id: - fail(f"{method.upper()} {path} has no operationId") - if not isinstance(summary, str) or not summary: - fail(f"{method.upper()} {path} has no summary") - if not isinstance(description, str) or not description: - fail(f"{method.upper()} {path} has no description") - if operation_id in seen_ids: - fail(f"duplicate operationId {operation_id}") - seen_ids.add(operation_id) - endpoint_slug = reference_pages.get((path, method)) - if not endpoint_slug: - fail(f"{method.upper()} {path} has no API reference page") - - parameters = operation.get("parameters", []) - if not isinstance(parameters, list): - fail(f"{method.upper()} {path} has invalid parameters") - parameter_names = frozenset( - parameter["name"] - for parameter in parameters - if isinstance(parameter, dict) and isinstance(parameter.get("name"), str) - ) - operations.append( - Operation( - path=path, - method=method, - operation_id=operation_id, - endpoint_slug=endpoint_slug, - summary=summary, - pricing=validate_pricing(f"{method.upper()} {path}", operation["x-aisa-pricing"]), - parameter_names=parameter_names, - ) - ) - - found_ids = {operation.operation_id for operation in operations} - missing = sorted(EXPECTED_OPERATION_IDS - found_ids) - unexpected = sorted(found_ids - EXPECTED_OPERATION_IDS) - if missing or unexpected: - details = [] - if missing: - details.append(f"missing operation IDs: {', '.join(missing)}") - if unexpected: - details.append(f"unexpected operation IDs: {', '.join(unexpected)}") - fail("; ".join(details)) - if len(operations) != len(EXPECTED_OPERATION_IDS): - fail(f"expected exactly {len(EXPECTED_OPERATION_IDS)} pricing operations, found {len(operations)}") - return operations - - -def category(operation: Operation) -> str: - driver_names = {driver["param"] for driver in operation.pricing["cost_drivers"]} - if driver_names == {"(none)"}: - return "fixed" - if "limit" in driver_names: - return "rows" - return "dimensions" - - -def price(value: float | int) -> str: - return f"${value:.2f}" - - -def drivers_en(operation: Operation) -> str: - return "; ".join( - f"`{driver['param']}`: {driver['effect']}" - for driver in operation.pricing["cost_drivers"] - ) - + location = f"{method.upper()} {path}" + if not isinstance(pricing, dict): + fail(f"{location} has no x-aisa-pricing object") + if not isinstance(description, str) or not description.strip(): + fail(f"{location} has no description") + operation["description"] = f"{without_prior_notice(description)}\n\n{notice(pricing, location)}\n" + operation_count += 1 -def driver_is_controllable(operation: Operation, driver_name: str) -> bool: - if driver_name == "periods": - return {"start_date", "end_date"}.issubset(operation.parameter_names) - return driver_name in operation.parameter_names - - -def controllable_drivers(operation: Operation) -> list[str]: - return [ - driver["param"] - for driver in operation.pricing["cost_drivers"] - if driver["param"] != "(none)" and driver_is_controllable(operation, driver["param"]) - ] - - -def provider_controlled_drivers(operation: Operation) -> list[str]: - return [ - driver["param"] - for driver in operation.pricing["cost_drivers"] - if driver["param"] != "(none)" and not driver_is_controllable(operation, driver["param"]) - ] - - -def display_example_en(operation: Operation) -> tuple[str, str]: - raw_example = operation.pricing["example"] - uncontrolled = provider_controlled_drivers(operation) - if category(operation) == "rows" and uncontrolled: - exposure, _, _ = raw_example.partition("; limit=") - return ( - "Published maximum-exposure example", - f"`{exposure}`. The source's `limit=...` text is a metering illustration only; " - "this endpoint does not accept `limit`.", - ) - if category(operation) == "dimensions" and uncontrolled: - names = ", ".join(f"`{name}`" for name in uncontrolled) - return ( - "Provider-controlled lower-bound example", - f"`{raw_example.rstrip('.')}`. {names} are provider-controlled for this endpoint, not caller-selectable request parameters.", - ) - return "Current schedule example", f"`{raw_example}`" - - -def control_en(operation: Operation) -> str: - operation_category = category(operation) - if operation_category == "fixed": - return "The published credit charge is fixed for this request type." - if operation_category == "rows": - if "limit" in operation.parameter_names: - return "Use the smallest meaningful `limit`; returned rows drive the credit cost." - return ( - "This row-priced operation has no documented `limit` parameter and does not accept `limit`. Do not promise that a caller can reduce " - "its cost with `limit`; use the documented example and cap as the exposure of one accepted request." - ) - controllable = controllable_drivers(operation) - uncontrolled = provider_controlled_drivers(operation) - if not controllable: - names = ", ".join(f"`{name}`" for name in uncontrolled) - return ( - f"The formula includes provider-controlled dimensions ({names}) that are not accepted request parameters. " - "The documentation does not publish an upper bound, so the example is a lower bound, not an approval cap. " - "Do not execute this operation under the approval-first contract until a documented maximum is available." - ) - control_names = ", ".join( - "the `start_date`/`end_date` range" if name == "periods" else f"`{name}`" - for name in controllable - ) - result = f"Cost varies with {control_names}; set the smallest required scope and obtain a budget decision before execution." - if uncontrolled: - names = ", ".join(f"`{name}`" for name in uncontrolled) - result += f" {names} remain provider-controlled." - return result - - -def generated_disclosure(operation: Operation) -> str: - pricing = operation.pricing - example_label, example = display_example_en(operation) - return "\n".join( - ( - DISCLOSURE_START, - "**Pricing (generated from `x-aisa-pricing`):** " - f"`{pricing['credit_rate']}` at `{price(pricing['credit_price_usd'])}` per credit. " - f"Formula: `{pricing['credit_formula']}`. Cost drivers: {drivers_en(operation)}. " - f"{example_label}: {example}", - "", - "**IMPORTANT:** SimilarWeb is a classic dynamic and potentially high-cost API. " - f"{control_en(operation)} Read [Agent Quickstart](/agent-quickstart#paid-api-approval-first) " - "and obtain explicit approval before a paid request.", - DISCLOSURE_END, - ) - ) - - -def strip_generated_disclosure(description: str) -> str: - matches = list(DISCLOSURE_PATTERN.finditer(description)) - if len(matches) > 1: - fail("an operation description contains multiple generated pricing disclosures") - return DISCLOSURE_PATTERN.sub("", description).rstrip() - - -def render_source(source: dict[str, Any], operations: list[Operation]) -> str: - rendered = copy.deepcopy(source) - for operation in operations: - target = rendered["paths"][operation.path][operation.method] - base_description = strip_generated_disclosure(target["description"]) - target["description"] = f"{base_description}\n\n{generated_disclosure(operation)}\n" - responses = target.get("responses") - if not isinstance(responses, dict) or not isinstance(responses.get("200"), dict): - fail(f"{operation.method.upper()} {operation.path} has no 200 response for settlement headers") - responses["200"]["headers"] = copy.deepcopy(SETTLEMENT_RESPONSE_HEADERS) - - source_metadata = { - (operation.path, operation.method): operation.pricing for operation in collect_operations(source) - } - rendered_metadata = { - (operation.path, operation.method): rendered["paths"][operation.path][operation.method]["x-aisa-pricing"] - for operation in operations - } - if rendered_metadata != source_metadata: - fail("generation attempted to change x-aisa-pricing metadata") - return json.dumps(rendered, indent=2, ensure_ascii=False) + "\n" - - -def expected_outputs(source: dict[str, Any]) -> dict[Path, str]: - operations = collect_operations(source) - return { - SOURCE_PATH: render_source(source, operations), - } - - -def check_outputs(outputs: dict[Path, str]) -> list[Path]: - return [path for path, expected in outputs.items() if not path.exists() or path.read_text(encoding="utf-8") != expected] + if operation_count == 0: + fail("OpenAPI source has no HTTP operations") + return json.dumps(source, indent=2, ensure_ascii=False) + "\n" def main() -> None: parser = argparse.ArgumentParser() mode = parser.add_mutually_exclusive_group(required=True) - mode.add_argument("--write", action="store_true", help="write generated pricing surfaces") - mode.add_argument("--check", action="store_true", help="fail if generated pricing surfaces are stale") + mode.add_argument("--write", action="store_true", help="refresh endpoint disclosures") + mode.add_argument("--check", action="store_true", help="fail when disclosures are stale") args = parser.parse_args() - outputs = expected_outputs(load_source()) - stale = check_outputs(outputs) + expected = render(json.loads(SOURCE_PATH.read_text(encoding="utf-8"))) + current = SOURCE_PATH.read_text(encoding="utf-8") if args.check: - if stale: - rendered_paths = ", ".join(str(path.relative_to(ROOT)) for path in stale) - raise SystemExit(f"SimilarWeb pricing surfaces are stale: {rendered_paths}. Run --write.") - print(f"SimilarWeb pricing surfaces are current: {len(EXPECTED_OPERATION_IDS)} operations") + if current != expected: + fail("endpoint disclosures are stale; run scripts/generate_similarweb_pricing_docs.py --write") + print("SimilarWeb pricing disclosures are current") return - for path in stale: - path.parent.mkdir(parents=True, exist_ok=True) - path.write_text(outputs[path], encoding="utf-8") - print(f"updated {path.relative_to(ROOT)}") - if not stale: - print(f"SimilarWeb pricing surfaces already current: {len(EXPECTED_OPERATION_IDS)} operations") + if current == expected: + print("SimilarWeb pricing disclosures already current") + return + SOURCE_PATH.write_text(expected, encoding="utf-8") + print(f"updated {SOURCE_PATH.relative_to(ROOT)}") if __name__ == "__main__": diff --git a/scripts/validate_similarweb_mintlify.py b/scripts/validate_similarweb_mintlify.py deleted file mode 100644 index c6c20dbf..00000000 --- a/scripts/validate_similarweb_mintlify.py +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env python3 -"""Validate the SimilarWeb endpoint disclosure and approval contract in Mintlify. - -The full repository currently contains unrelated historical MDX parse warnings. -This script copies the agent-quickstart policy pages, all SimilarWeb endpoint -pages, and their OpenAPI source into a temporary -Mintlify project, then runs the same strict ``mint validate`` command used in -CI. It validates the surfaces this pricing contract owns without mutating or -suppressing diagnostics in the source repository. -""" - -from __future__ import annotations - -import argparse -import json -import shutil -import subprocess -import tempfile -from pathlib import Path - - -ROOT = Path(__file__).resolve().parents[1] -POLICY_PATHS = ( - ROOT / "agent-quickstart.mdx", - ROOT / "zh" / "agent-quickstart.mdx", -) -API_REFERENCE_DIR = ROOT / "api-reference" / "similarweb" -OPENAPI_PATH = ROOT / "openapi" / "similarweb.json" - - -def copy_into_fixture(source: Path, fixture_root: Path) -> None: - target = fixture_root / source.relative_to(ROOT) - target.parent.mkdir(parents=True, exist_ok=True) - shutil.copy2(source, target) - - -def build_fixture(fixture_root: Path) -> int: - endpoint_pages = sorted(API_REFERENCE_DIR.glob("*.mdx")) - if not endpoint_pages: - raise SystemExit("Mintlify fixture has no SimilarWeb endpoint pages") - - for path in (*POLICY_PATHS, *endpoint_pages, OPENAPI_PATH): - if not path.exists(): - raise SystemExit(f"Mintlify fixture input is missing: {path.relative_to(ROOT)}") - copy_into_fixture(path, fixture_root) - - pages = [ - "agent-quickstart", - "zh/agent-quickstart", - *(path.relative_to(ROOT).with_suffix("").as_posix() for path in endpoint_pages), - ] - config = { - "name": "SimilarWeb pricing validation", - "theme": "mint", - "colors": {"primary": "#F76B15"}, - "navigation": { - "groups": [ - { - "group": "Paid API approval and SimilarWeb endpoints", - "pages": pages, - } - ] - }, - } - (fixture_root / "docs.json").write_text( - json.dumps(config, indent=2) + "\n", - encoding="utf-8", - ) - return len(endpoint_pages) - - -def main() -> None: - parser = argparse.ArgumentParser() - parser.add_argument( - "--prepare-only", - action="store_true", - help="validate the fixture inputs and configuration without running Mintlify", - ) - args = parser.parse_args() - - with tempfile.TemporaryDirectory(prefix="aisa-similarweb-mintlify-") as directory: - fixture_root = Path(directory) - endpoint_count = build_fixture(fixture_root) - if args.prepare_only: - print(f"Mintlify fixture prepared: {endpoint_count} SimilarWeb endpoint pages") - return - subprocess.run( - ["npx", "--yes", "mint@4.2.854", "validate"], - cwd=fixture_root, - check=True, - ) - print(f"Mintlify validated SimilarWeb fixture: {endpoint_count} endpoint pages") - - -if __name__ == "__main__": - main() diff --git a/zh/agent-quickstart.mdx b/zh/agent-quickstart.mdx index e584013d..3f600fe1 100644 --- a/zh/agent-quickstart.mdx +++ b/zh/agent-quickstart.mdx @@ -13,24 +13,18 @@ description: >- ## 重要:付费和高成本 API 的先批准后执行合同 -该合同适用于每一个付费、动态计价或可能高成本的 API endpoint,无论它是直接调用、通过 Agent Skill,还是通过 MCP 数据工具调用。这是一条安全边界,不是价格发现流程。 +该合同适用于每一个付费、动态计价或可能高成本的 API endpoint,无论它是直接调用、通过 Agent Skill,还是通过 MCP 数据工具调用。 ```xml ``` -**典型场景 — SimilarWeb:** SimilarWeb 是动态计价、可能高成本的数据 API。请读取匹配 endpoint 的 [`x-aisa-pricing`](https://aisa.one/openapi.yaml) 元数据;只有请求维度可界定时才计算成本,并在数据调用前取得明确批准。元数据提供公式和已记录的成本暴露,不会形成报价 API,也不构成数据调用授权。 +**典型场景 — SimilarWeb:** 请读取匹配 endpoint 的 [`x-aisa-pricing`](https://aisa.one/openapi.yaml) 元数据;只有请求可界定时才计算成本,并在数据调用前取得明确批准。 ## 最小设置事实 diff --git a/zh/evaluate/pricing.mdx b/zh/evaluate/pricing.mdx index c8104b15..87d8397d 100644 --- a/zh/evaluate/pricing.mdx +++ b/zh/evaluate/pricing.mdx @@ -11,7 +11,6 @@ AIsa 对模型推理和计费型 API 能力采用按量计费。具体价格取 - [AI 模型价格](/zh/guides/pricing/ai-model-pricing-llm-inference):模型计费说明。 - [按次调用 API 价格](/zh/guides/pricing/per-call-api-pricing):API 计费说明。 -- 匹配的 SimilarWeb endpoint 文档及其 `x-aisa-pricing` 元数据:SimilarWeb 的公式化端点价格。 - [钱包与支付](/zh/guides/pricing/wallet):充值和余额行为。 - [用量日志](/zh/guides/dashboard/usage-logs):账户的实际用量。 - 实时模型目录或具体 API 页面:当前能力的上下文信息。 @@ -58,10 +57,9 @@ AIsa 对模型推理和计费型 API 能力采用按量计费。具体价格取 ## 上线前的验证 -- 对任何付费或可能高成本的 API,不得通过请求发现价格或验证配置。必须先展示精确 scope、公式或价格规则和已记录的最大上限,再取得明确批准。SimilarWeb 是动态成本的典型场景;如果没有已记录的最大上限,不得按先批准后执行合同调用该端点。 - 确认精确的模型 ID 或 endpoint。 - 查看当前的计价单位。 -- 对 SimilarWeb 之外的 API,跑一个有代表性的小请求。 +- 跑一个有代表性的小请求。 - 检查用量记录。 - 衡量完整工作流,而不只是单次调用。 - 在放量之前先加上预算告警。 diff --git a/zh/guides/pricing.mdx b/zh/guides/pricing.mdx index f08d7eb9..58979898 100644 --- a/zh/guides/pricing.mdx +++ b/zh/guides/pricing.mdx @@ -59,9 +59,7 @@ AI 模型 API 根据 token 用量计费。 如需查看固定按次计费 API 的 endpoint 级价格细节和计费行为,请查看[按次调用 API 价格](/zh/guides/pricing/per-call-api-pricing)。 -### 公式计费的数据 API - -部分付费数据 API(包括 SimilarWeb)使用 credit 公式,而不是固定的按次价格。发起付费请求前,请阅读匹配 endpoint 文档及其机器可读计价说明;只有请求范围有已记录的最大上限时才计算成本,并取得明确批准。 +部分付费数据 API(包括 SimilarWeb)使用 credit 公式,而不是固定的按次价格。发起付费请求前,请阅读匹配 endpoint 文档及其机器可读计价说明;如果没有已记录的最大上限,不得按先批准后执行合同调用。 ## 如何选择正确的计费模型 From faad5799e6d2e08c6aac3c09ab711dc82f5f5b51 Mon Sep 17 00:00:00 2001 From: idan Date: Wed, 2 Sep 2026 14:36:55 +0800 Subject: [PATCH 7/8] docs: require a separate approval turn for paid data --- agent-quickstart.mdx | 10 +++-- llms.txt | 2 +- openapi/similarweb.json | 46 ++++++++++----------- scripts/generate_similarweb_pricing_docs.py | 5 ++- zh/agent-quickstart.mdx | 6 +-- 5 files changed, 36 insertions(+), 33 deletions(-) diff --git a/agent-quickstart.mdx b/agent-quickstart.mdx index d841ccdb..51c4a370 100644 --- a/agent-quickstart.mdx +++ b/agent-quickstart.mdx @@ -20,14 +20,16 @@ This contract applies to every paid, dynamically priced, or potentially high-cos Read the matching endpoint documentation and published pricing declaration. Docs, /v1/models, and capability or MCP discovery are allowed before approval. - State the exact endpoint and scope, formula or rate, and documented maximum - USD exposure; then obtain explicit approval for that scope and cap. + STOP: a request to collect, research, or report data is not approval. State + the exact endpoint and scope, formula or rate, and documented maximum USD + exposure; then wait for a separate user message explicitly approving that + scope and cap. If a provider-controlled dimension has no documented upper bound, do not execute: an example or user-stated budget is not an enforceable cap. - Do not use a paid call to discover price, probe, test, or "just check"; - do not invent or call a quote API. + Do not run a paid data call in the planning turn, use the initial request as + consent, or use a paid call to discover price, probe, test, or "just check". Execute only the approved request. If its endpoint, scope, or maximum diff --git a/llms.txt b/llms.txt index 4fdf408e..486bf634 100644 --- a/llms.txt +++ b/llms.txt @@ -14,7 +14,7 @@ Use this index to choose the smallest relevant documentation set. For product di - [Rate Limits](https://aisa.one/docs/api-reference/rate-limits): limits and relevant headers. ## Navigate by Goal diff --git a/openapi/similarweb.json b/openapi/similarweb.json index 90e12c86..d07c4e6a 100644 --- a/openapi/similarweb.json +++ b/openapi/similarweb.json @@ -38,7 +38,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Traffic & Engagement", - "description": "Traffic & Engagement. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Traffic & Engagement. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_traffic_engagement", "parameters": [ { @@ -251,7 +251,7 @@ "example": "minimal (1 month) = 2 credits ($0.20); cost grows with periods." }, "summary": "Website Ranking", - "description": "Website Ranking. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `2 credits / (month)` at `$0.10` per credit. Formula: `credits = 2 x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Website Ranking. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `2 credits / (month)` at `$0.10` per credit. Formula: `credits = 2 x periods`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_ranking", "parameters": [ { @@ -418,7 +418,7 @@ "example": "minimal (1 month) = 1 credit ($0.10); cost grows with periods." }, "summary": "PPC Spend", - "description": "PPC Spend. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (month)` at `$0.10` per credit. Formula: `credits = 1 x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "PPC Spend. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (month)` at `$0.10` per credit. Formula: `credits = 1 x periods`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_ppc_spend", "parameters": [ { @@ -579,7 +579,7 @@ "example": "20 rows = 20 credits ($2.00); limit=5 = 5 credits ($0.50)" }, "summary": "Top Sites Ranking", - "description": "Top Sites Ranking. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(1 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Top Sites Ranking. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(1 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_top_sites_ranking", "parameters": [ { @@ -705,7 +705,7 @@ "example": "minimal (1 month) = 7 credits ($0.70); cost grows with periods." }, "summary": "Marketing Channel Sources", - "description": "Marketing Channel Sources. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Marketing Channel Sources. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_marketing_channel_sources_legacy", "parameters": [ { @@ -880,7 +880,7 @@ "example": "20 rows = 80 credits ($8.00); limit=5 = 20 credits ($2.00)" }, "summary": "Referrals", - "description": "Referrals. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `4 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(4 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Referrals. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `4 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(4 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_referrals", "parameters": [ { @@ -1077,7 +1077,7 @@ "example": "20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)" }, "summary": "Ad Networks", - "description": "Ad Networks. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Ad Networks. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_ad_networks", "parameters": [ { @@ -1275,7 +1275,7 @@ "example": "20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)" }, "summary": "SimilarSites", - "description": "SimilarSites. Response follows the SimilarWeb v5 envelope (meta + data). Date window (upstream SimilarWeb constraint): start_date and end_date must span EXACTLY 3 consecutive months — a 1- or 2-month span is rejected with upstream error 120 ('must span exactly 3 month(s)'). That span must also be SimilarWeb's most recent supported window, which advances forward each month; an older or out-of-range span is rejected with error 101 ('Dates not in range'). In practice, request the three most recent completed months (e.g. if the latest published month is 2026-07, use start_date=2026-05 and end_date=2026-07). To read the exact currently-supported range, call SimilarWeb's /describe endpoint for this API.\n\n**Pricing (from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "SimilarSites. Response follows the SimilarWeb v5 envelope (meta + data). Date window (upstream SimilarWeb constraint): start_date and end_date must span EXACTLY 3 consecutive months — a 1- or 2-month span is rejected with upstream error 120 ('must span exactly 3 month(s)'). That span must also be SimilarWeb's most recent supported window, which advances forward each month; an older or out-of-range span is rejected with error 101 ('Dates not in range'). In practice, request the three most recent completed months (e.g. if the latest published month is 2026-07, use start_date=2026-05 and end_date=2026-07). To read the exact currently-supported range, call SimilarWeb's /describe endpoint for this API.\n\n**Pricing (from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_similar_sites", "parameters": [ { @@ -1478,7 +1478,7 @@ "example": "1 request = 8 credits ($0.80)" }, "summary": "Demographics", - "description": "Demographics. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must fall in the SAME month (exactly one monthly bucket).\n\n**Pricing (from `x-aisa-pricing`):** `8 credits (fixed)` at `$0.10` per credit. Formula: `credits = 8 (fixed per request)`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Demographics. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must fall in the SAME month (exactly one monthly bucket).\n\n**Pricing (from `x-aisa-pricing`):** `8 credits (fixed)` at `$0.10` per credit. Formula: `credits = 8 (fixed per request)`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_demographics", "parameters": [ { @@ -1673,7 +1673,7 @@ "example": "minimal (1 month) = 7 credits ($0.70); cost grows with periods." }, "summary": "Deduplicated Audience", - "description": "Deduplicated Audience. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Deduplicated Audience. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 120 monthly buckets.\n\n**Pricing (from `x-aisa-pricing`):** `7 credits / (month)` at `$0.10` per credit. Formula: `credits = 7 x periods`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_deduplicated_audience", "parameters": [ { @@ -1860,7 +1860,7 @@ "example": "20 rows = 100 credits ($10.00); limit=5 = 25 credits ($2.50)" }, "summary": "Audience Interest", - "description": "Audience Interest. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Audience Interest. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `5 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(5 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_audience_interest", "parameters": [ { @@ -2067,7 +2067,7 @@ "example": "5 rows = 10 credits ($1.00); limit=5 = 10 credits ($1.00)" }, "summary": "Audience Overlap", - "description": "Audience Overlap. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n**Pricing (from `x-aisa-pricing`):** `2 / row (max 5 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 5`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Audience Overlap. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n**Pricing (from `x-aisa-pricing`):** `2 / row (max 5 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 5`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_audience_overlap", "parameters": [ { @@ -2205,7 +2205,7 @@ "example": "1 request = 10 credits ($1.00)" }, "summary": "Website Technologies", - "description": "Website Technologies. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must be the SAME month, and that month must be the latest available data month — a single monthly bucket that advances as SimilarWeb refreshes its data, and which may differ by country. Supplying any other month returns SimilarWeb error_code 101 (\"Dates not in range\"); the error message states the currently-allowed range.\n\n**Pricing (from `x-aisa-pricing`):** `10 credits (fixed)` at `$0.10` per credit. Formula: `credits = 10 (fixed per request)`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Website Technologies. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: start_date and end_date must be the SAME month, and that month must be the latest available data month — a single monthly bucket that advances as SimilarWeb refreshes its data, and which may differ by country. Supplying any other month returns SimilarWeb error_code 101 (\"Dates not in range\"); the error message states the currently-allowed range.\n\n**Pricing (from `x-aisa-pricing`):** `10 credits (fixed)` at `$0.10` per credit. Formula: `credits = 10 (fixed per request)`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_technologies", "parameters": [ { @@ -2411,7 +2411,7 @@ "example": "20 rows = 60 credits ($6.00); limit=5 = 15 credits ($1.50)" }, "summary": "Popular Pages", - "description": "Popular Pages. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n**Pricing (from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Popular Pages. Response follows the SimilarWeb v5 envelope (meta + data). Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n**Pricing (from `x-aisa-pricing`):** `3 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_popular_pages", "parameters": [ { @@ -2609,7 +2609,7 @@ "example": "20 rows = 40 credits ($4.00); limit=5 = 10 credits ($1.00)" }, "summary": "Website Subdomains", - "description": "Website Subdomains. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `2 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Website Subdomains. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `2 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(2 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_subdomains", "parameters": [ { @@ -2797,7 +2797,7 @@ "example": "20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)" }, "summary": "Keyword Competitors", - "description": "Keyword Competitors. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.03 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.03 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Keyword Competitors. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.03 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.03 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_keyword_competitors", "parameters": [ { @@ -2992,7 +2992,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "Website Keywords", - "description": "Website Keywords. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 3 monthly buckets. Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n**Pricing (from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Website Keywords. Response follows the SimilarWeb v5 envelope (meta + data). Date constraint: the start_date-end_date span must cover between 1 and 3 monthly buckets. Note: `data` may arrive grouped as an array of arrays; billing counts rows across all groups.\n\n**Pricing (from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_keywords", "parameters": [ { @@ -3232,7 +3232,7 @@ "example": "20 rows = 1 credit ($0.10); limit=5 = 1 credit ($0.10)" }, "summary": "SERP Players - Clicks over time", - "description": "SERP Players - Clicks over time. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.02 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.02 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "SERP Players - Clicks over time. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.02 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.02 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_serp_players_timeseries", "parameters": [ { @@ -3393,7 +3393,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "SERP Players - Aggregated", - "description": "SERP Players - Aggregated. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.07 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.07 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "SERP Players - Aggregated. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.07 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.07 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_serp_players_aggregated", "parameters": [ { @@ -3584,7 +3584,7 @@ "example": "20 rows = 2 credits ($0.20); limit=5 = 1 credit ($0.10)" }, "summary": "Landing Pages", - "description": "Landing Pages. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Landing Pages. Response follows the SimilarWeb v5 envelope (meta + data).\n\n**Pricing (from `x-aisa-pricing`):** `0.1 / row (max 20 rows)` at `$0.10` per credit. Formula: `credits = ceil(0.1 x rows); rows capped at 20`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_landing_pages", "parameters": [ { @@ -3812,7 +3812,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Website Traffic Snapshot", - "description": "Latest-month traffic snapshot for a domain: visits plus core engagement metrics (average visit duration, bounce rate, pages per visit) in a single object. The most recent available month is selected automatically and echoed in meta.start_date / meta.end_date.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Latest-month traffic snapshot for a domain: visits plus core engagement metrics (average visit duration, bounce rate, pages per visit) in a single object. The most recent available month is selected automatically and echoed in meta.start_date / meta.end_date.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_website_traffic_snapshot", "parameters": [ { @@ -3952,7 +3952,7 @@ "example": "minimal (1 metric + 1 month) = 1 credit ($0.10); cost grows with metrics and periods." }, "summary": "Website Traffic Trend", - "description": "Monthly traffic time series for a domain over the recent available window (data.points, one entry per month). The window is selected automatically and echoed in meta.start_date / meta.end_date.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Monthly traffic time series for a domain over the recent available window (data.points, one entry per month). The window is selected automatically and echoed in meta.start_date / meta.end_date.\n\n**Pricing (from `x-aisa-pricing`):** `1 credit / (metric x month)` at `$0.10` per credit. Formula: `credits = 1 x metrics x periods`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_website_traffic_trend", "parameters": [ { @@ -4127,7 +4127,7 @@ "example": "10 rows = 30 credits ($3.00); limit=5 = 15 credits ($1.50)" }, "summary": "Website Top Geographies", - "description": "Top countries by share of a domain's traffic for the latest available month (data.countries, up to 10 rows with country_code, country_name, share and visits). Geography coverage is worldwide (ww) and fixed: a country parameter is not accepted for this endpoint.\n\n**Pricing (from `x-aisa-pricing`):** `3 / row (max 10 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 10`. Before a paid data call, follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval.\n", + "description": "Top countries by share of a domain's traffic for the latest available month (data.countries, up to 10 rows with country_code, country_name, share and visits). Geography coverage is worldwide (ww) and fixed: a country parameter is not accepted for this endpoint.\n\n**Pricing (from `x-aisa-pricing`):** `3 / row (max 10 rows)` at `$0.10` per credit. Formula: `credits = ceil(3 x rows); rows capped at 10`. **IMPORTANT:** a request to gather data is not approval. Before a paid data call, present scope and documented maximum, then wait for a separate explicit approval message; follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first).\n", "operationId": "get_similarweb_website_top_geographies", "parameters": [ { diff --git a/scripts/generate_similarweb_pricing_docs.py b/scripts/generate_similarweb_pricing_docs.py index ebb98163..8bdad7ef 100644 --- a/scripts/generate_similarweb_pricing_docs.py +++ b/scripts/generate_similarweb_pricing_docs.py @@ -47,8 +47,9 @@ def notice(pricing: dict[str, Any], location: str) -> str: f"`{required_text(pricing, 'credit_rate', location)}` at " f"`{price_usd(pricing.get('credit_price_usd'), location)}` per credit. " f"Formula: `{required_text(pricing, 'credit_formula', location)}`. " - "Before a paid data call, follow " - "[Agent Quickstart](/agent-quickstart#paid-api-approval-first) and obtain explicit approval." + "**IMPORTANT:** a request to gather data is not approval. Before a paid data call, " + "present scope and documented maximum, then wait for a separate explicit approval message; " + "follow [Agent Quickstart](/agent-quickstart#paid-api-approval-first)." ) diff --git a/zh/agent-quickstart.mdx b/zh/agent-quickstart.mdx index 3f600fe1..bd6fc924 100644 --- a/zh/agent-quickstart.mdx +++ b/zh/agent-quickstart.mdx @@ -19,12 +19,12 @@ description: >-