# API reference — Alibaba RFQ Leads AI

For integrators and agents: one real dataset item, the `OUTPUT` record's keys, which call runs what, every flag and the
free-tier rule. The README on the Store page links here.

## One dataset item

Cut from a local run of the free demo with the AI on (2026-10-23) — a sample record carrying its labelled sample AI
verdict (`assessedBy` / `aiModel`: `sample`), so `fitReason` starts with the sample note and `chargedEvent` is `demo`;
a live row has the same keys with `aiModel` naming the real model:

```json
{
  "url": "https://sourcing.alibaba.com/rfq/rfq_search_list.htm?searchText=cotton+t-shirt&sample=1",
  "itemId": "sample-rfq-1",
  "rfqId": "sample-rfq-1",
  "dedupeKey": "alibaba-rfq:sample-rfq-1",
  "subject": "Organic cotton crew neck t-shirts with printed logo, 180 gsm",
  "subjectEnglish": "Organic cotton crew neck t-shirts with printed logo, 180 gsm",
  "description": "We are a US streetwear brand looking for 3,000 organic cotton crew neck t-shirts, 180 gsm, sizes S-XXL, 4 colors. Screen printed logo on chest and custom neck label. GOTS certified fabric required. Target price USD 3.20 per piece FOB. Delivery to Los Angeles within 45 days.",
  "descriptionEnglish": null,
  "language": "en",
  "quantity": 3000.0,
  "quantityUnit": "Piece/Pieces",
  "buyerName": "Jason M.",
  "buyerCountry": "United States",
  "buyerCountryCode": "US",
  "postedAt": "2026-10-22T16:50:37Z",
  "quotesLeft": 4,
  "extraQuoteSeats": 5,
  "buyerStars": 3,
  "buyerTags": [
    "email verified",
    "experienced buyer"
  ],
  "hasAttachments": true,
  "quoteUrl": "https://sourcing.alibaba.com/rfq/rfq_search_list.htm?searchText=cotton+t-shirt&sample=1",
  "contactRoute": "https://sourcing.alibaba.com/rfq/rfq_search_list.htm?searchText=cotton+t-shirt&sample=1",
  "specs": [
    {
      "name": "material",
      "value": "organic cotton",
      "quote": "organic cotton"
    },
    {
      "name": "weight",
      "value": "180 gsm",
      "quote": "180 gsm"
    },
    {
      "name": "sizes",
      "value": "S-XXL",
      "quote": "sizes S-XXL"
    },
    {
      "name": "colors",
      "value": "4 colors",
      "quote": "4 colors"
    },
    {
      "name": "certification",
      "value": "GOTS certified",
      "quote": "GOTS certified"
    }
  ],
  "targetPrice": 3.2,
  "targetPriceCurrency": "USD",
  "incoterm": "FOB",
  "destination": "Los Angeles",
  "deadline": "45 days",
  "customisation": [
    "Screen printed logo on chest",
    "custom neck label"
  ],
  "hsCodeSuggested": "610910",
  "hsConfidence": 0.95,
  "ruleScore": 99,
  "fitScore": 95,
  "score": 95,
  "label": "hot",
  "assessedBy": "sample",
  "fitReason": "(Sample request — its link opens an Alibaba search, not a real request.) Exact match for cotton t-shirt product line and 180 gsm weight specification; Order quantity of 3,000 pieces is above our MOQ of 500 pieces — \"3,000 organic cotton crew neck t-shirts, 180 gsm\"",
  "scoreReasons": [
    "Exact match for cotton t-shirt product line and 180 gsm weight specification",
    "Order quantity of 3,000 pieces is above our MOQ of 500 pieces",
    "Buyer is located in the United States, one of our key export markets",
    "GOTS certification matches our GOTS certified production"
  ],
  "matchedProducts": [
    "cotton t-shirt"
  ],
  "temperature": "hot",
  "quoteToday": true,
  "quotePlan": null,
  "quoteRank": null,
  "quotePlanReason": null,
  "quoteReply": "Hello, thank you for your inquiry for 3,000 organic cotton crew neck t-shirts, 180 gsm, with custom logo printing and custom neck label. We are Sunrise Knit Exports from Tiruppur, India, a manufacturer of cotton t-shirts and polo shirts. We are GOTS and OEKO-TEX certified and offer custom logo printing and embroidery. Our MOQ is 500 pieces per design, and our standard lead time is 25-30 days. We quote FOB Chennai or Tuticorin. Please share your size breakdown and colour details so we can send you an accurate quotation. We look forward to hearing from you.",
  "replyLanguage": "en",
  "flags": [
    "catalogue_match",
    "above_moq",
    "in_export_market",
    "quote_today",
    "verified_buyer",
    "experienced_buyer",
    "has_attachments",
    "target_price_stated",
    "incoterm_stated",
    "customisation"
  ],
  "targetFlagsMatched": [],
  "aiModel": "sample",
  "searchTerm": "cotton t-shirt",
  "sourceActor": "list",
  "chargedEvent": "demo",
  "billedAs": "qualified-buying-lead-ai",
  "scrapedAt": "2026-10-22T19:50:57+00:00"
}
```

Upsert on `dedupeKey`. Sort one run on `score`; threshold and trend across runs on `ruleScore` (`assessedBy` says which
scale a row's `score` is on).

## `OUTPUT` keys

The same record is written as `RUN_SUMMARY`. Keys of that run (a live run adds `scheduleInput`, `scheduleTaskUrl`,
`suggestedTerms`, `sourceStatus` …; a refused or failed source writes `ok: false`, `outcome`, `sourceError`):

| Key | Type |
|---|---|
| `mode` | string |
| `qualified` | integer |
| `candidates` | integer |
| `stats` | object |
| `chargedEvents` | object |
| `unchargedEvents` | null |
| `freeTierThisRun` | integer |
| `demoRows` | integer |
| `freeTierRemaining` | null |
| `freeAiReserve` | null |
| `chargeSplit` | null |
| `demoIgnoredFields` | null |
| `switchedToLive` | null |
| `demoTextsDropped` | null |
| `demoTextsSearched` | null |
| `budgetLimitReached` | boolean |
| `targetFlags` | null |
| `yieldByQuery` | object |
| `webhook` | null |
| `dedupeStore` | null |
| `aiError` | string |
| `trend` | null |
| `history` | null |
| `historyDataset` | null |
| `scheduledSizing` | null |
| `firstRunBackfill` | null |
| `scanCapHit` | null |
| `sourceSpendCapHit` | null |
| `seedsRolled` | null |
| `presetApplied` | null |
| `quotePlan` | null |
| `suggestedTerms` | null |
| `aiCoverage` | object |
| `aiTrial` | null |
| `aiTokens` | null |
| `ok` | boolean |
| `outcome` | string |
| `sourceError` | null |
| `sourceStatus` | null |
| `demo` | null |
| `timing` | object |
| `scheduleInput` | object |
| `timeSaved` | null |
| `reviewAsked` | null |
| `leadDigest` | object |
| `reportUrl` | null |
| `nextSteps` | array |

## Which call runs what — demo, live search or your own rows

| Input shape | `OUTPUT.mode` | Can it charge? |
|---|---|---|
| `{}` or the untouched form | `demo` | no — sample rows are `chargedEvent: demo` |
| the sample + your own `products` typed next to it | `live` | yes; the source scan on your account, capped |
| the same with `autoSwitchToLive: false` | `demo` | no — the status names the products it did not search |
| `products` (any `sourceMode` left at `actor`) | `live` | yes |
| `sourceMode: "list"` + your `itemsList` / `sourceMode: "dataset"` + `datasetId` | `list` / `dataset` | yes, no source run |

Every run writes `OUTPUT.mode`, so an agent can assert what it paid for.

## Flags (`targetFlags` values; `quoteToday` spelling works too)

| Flag | Meaning |
|---|---|
| `catalogue_match` | the request names one of your product lines |
| `above_moq` / `below_moq` | the quantity is at / below your MOQ |
| `in_export_market` | the buyer is in one of your export markets |
| `quote_today` | posted in the last 48 hours with quote seats left |
| `few_quotes_left` | only 1–2 quote seats left — answer first |
| `verified_buyer` / `experienced_buyer` | e-mail verified / experienced or completed orders via RFQ |
| `has_attachments` | drawings, photos or specs attached |
| `target_price_stated` / `incoterm_stated` | the request states a target price / an incoterm |
| `customisation` | logo, private label or custom packaging asked for |
| `non_english` | not in English — the AI tier translates it |

## The free tier and the AI reserve

Your first 25 qualified buying leads on this Actor are free — one free tier per Apify account, whatever the tier. When
the AI is on but unavailable for a run (no model access, a refused or rate-limited key), rule-scored rows use the free
units too, except the last 5: the AI reserve, kept for your first AI-assessed buying leads.
`OUTPUT.chargeSplit.freeKeptForAi` says how many are kept; the status says only "N free buying leads left".

## Webhook payload

`{"event": "buying_lead.qualified", "buying_lead": {…the dataset item…}, "runId": "…"}` per lead, or
`{"event": "buying_leads.qualified", "buying_leads": [{…}], "runId": "…"}` per batch (`webhookBatchSize`). A row
re-sent after a failed POST carries `"redelivery": true` (up to 7 days, never charged again).
