Trend-arb · internal · 28 Aug 2026

Twelve stages.
Only five spend money.

TikTok Shop US trend signal → 1688 sourcing → NZ Shopify landing page → Meta ads. This is the flight plan, not the pitch. It exists to show where cash enters, where the risk sits, and what is still blocked — everything else is sequence.

External API stages
5Apify ×5, plus FX, Shopify, Meta downstream
Free internal logic
4Buildable today, no token needed
Hard blockers
1Apify token — nothing runs without it
Cost / weekly cycle
$23Measured at BRONZE tier · test cost $0.25

00 / How to read thisConfidence is labelled. Don't skip it.

VERIFIED

Pulled live from the Apify API on 28 Aug 2026 — actor IDs, per-event pricing, and 30-day success rates. These are measured, not quoted from a listing page.

UNVERIFIED

Actor input schemas are not public — readable only with a token. Field names marked are the expected shape. Do not code against them until the real schema is read.

Model decision — locked

(a) Accept 2–4 week China→NZ ship times. No capital tied up, lower conversion. Every margin figure below therefore carries a refund provision, and the landing page must show an honest ETA. Under this model that provision is not optional — margin that ignores it is fiction.

Live test 28 Aug — the kill rule was wrong

The 1688 cost × 3.5 gate passes products that lose money. On the tested product (US$11.19 retail) the cheapest 1688 match was CNY 2.89 = NZ$0.68 — ×3.5 clears easily, yet the real net margin is −NZ$12.85 once freight is costed properly. Product cost is nearly irrelevant: a 40× swing in supplier price moves net by NZ$27, while CAC and freight move it far more. The gate is now a US retail price floor plus a weight ceiling, applied before the growth ranking. Full walkthrough in §01–03.

01 / The economicsWhy there has to be a price floor

The gate isn't about finding a cheap enough supplier. It's about whether the sale price can carry the costs that don't shrink when the product is cheap. Same business, same supplier country, same ad spend — two different products.

A — the product we testedUS$11.19 · 500g · CNY 2.89 from 1688

Customer paysNZ$18.80
− GST to IRD (15%)−NZ$2.45
− Product from 1688−NZ$0.68
− Shipping China→NZ−NZ$15.39
− Meta ads to win the sale−NZ$12.00
− Refund provision (6%)−NZ$1.13
You keep−NZ$12.85

B — identical, but a US$45 productUS$45 · 500g · CNY 50 — 17× dearer to buy

Customer paysNZ$75.60
− GST to IRD (15%)−NZ$9.86
− Product from 1688−NZ$11.75
− Shipping China→NZ−NZ$15.39
− Meta ads to win the sale−NZ$12.00
− Refund provision (6%)−NZ$4.54
You keep+NZ$22.06

B uses a product that costs 17× more to buy and still makes NZ$22 while A loses NZ$13. The only thing that changed is what you sell it for.

Now set product A's supplier cost to zero — the product is free. It still loses NZ$12.17. There is nothing left to cut, because the supplier was never the problem.

The two amber lines are why. Shipping and ads come to NZ$27.39 per sale whether you sell a $10 item or a $100 one. On an NZ$18.80 sale that is more than the entire sale. On an NZ$75.60 sale it is barely a third.

02 / FreightNZ$6.50 was wrong — it's weight-driven

My original NZ$6.50 was a placeholder and it was too low by between 1.3× and 7×. China Post ePacket publishes 23 CNY per parcel + 85 CNY/kg, capped at 2kg. That makes freight a function of weight, so weight becomes a selection criterion in its own right.

WeightFreight NZ$vs my placeholderNet on a US$45 item (CNY 15 product)
150 gNZ$8.401.3×+NZ$36.28
300 gNZ$11.401.8×+NZ$33.29
500 gNZ$15.392.4×+NZ$30.29
1 kgNZ$25.383.9×+NZ$20.30
1.5 kgNZ$35.375.4×+NZ$10.31
2 kg (hard cap)NZ$45.357.0×+NZ$0.33

03 / The floorWhat this makes the actual rule

Break-even and 25%-net retail price, at CAC NZ$12 with a CNY 15 product, by parcel weight:

WeightFreightBreak-even US retailUS retail for 25% net
150 gNZ$8.40US$17.75US$25.50
300 gNZ$11.40US$20.00US$28.75
500 gNZ$15.39US$22.75US$33.00
1 kgNZ$25.38US$30.25US$43.75

The working rule

US retail ≥ US$30 AND under 500g. Applied before the growth ranking, not after — otherwise the whole pipeline burns discovery, creative capture, reverse-image search and supplier lookup on products that were dead on arrival. A heavy cheap product is dead twice over.

What is still an estimate

CAC NZ$12 is invented — it is what Meta ads cost per sale, and nobody knows it until the first campaign runs. The ePacket rates are published but are the US lane; NZ is lower-volume and typically dearer, so treat these as a floor rather than a quote. Get a real number from CJ Dropshipping's calculator or a forwarder before committing. Every table above moves with those two inputs — but the shape holds: cheap or heavy products cannot carry a fixed per-sale cost.

04 / What the first real run foundThe keyword list is the whole ballgame

Same filters, same snapshot size, two keyword sets — and a 4× vs 72 outcome. Scanning "trending" broadly walks you straight into blocked categories.

Keyword setCleared price floorSurvived S4
Battery-heavy (led face mask, smart ring, massage gun)724 — 68 blocked as battery
Non-electronic (wig, hair extensions, silk pillowcase, leather bag, sunglasses)7472 — 1 blocked

The standout category: wigs and human hair

High AOV, high volume, light, no battery, no liquid. Live on TikTok Shop US: OQ HAIR wear-and-go glueless US$106.60 with 72,212 sold; 360 Wig US$213.33 / 19,957; Recool US$104.90 / 10,208. 1688 human-hair comparables run CNY 29–200 → net NZ$74–115 (42–64%). Supply concentrates in 浙江 and 河南/许昌 — Xuchang is the global wig manufacturing hub. Blissy silk pillowcase (US$79.96, 74,036 sold) is the other clean one.

Sourcing method depends on the photo, not the product

Reverse-image works on isolated objects — an LED mask product shot matched 30/30. It fails on model-worn goods: a wig photo returned ear stickers, hair dye and a comb, because the image is a person, not the product. For apparel, hair, anything worn — source by Chinese keyword via zen-studio/1688-wholesale-scraper instead.

And "cheapest" has now misled three times running: a US$299 LED mask matched a WiFi smart lock; price-ascending on wigs surfaced 化纤 synthetic party wigs at CNY 4.65 as if comparable to a US$106 human-hair HD lace front. A keyword or image hit is a candidate, never an equivalent — filter on spec, and use the median, never the minimum.

05 / S6bThe stage the funnel was missing

The original funnel filtered on price, weight, battery and margin — and never once asked whether the NZ market was already taken. That is the actual thing being looked for: overseas traction plus thin NZ supply.

NZ search volume is a lagging indicator. It measures what people here already know exists. Something trending overseas and not yet sold here shows low NZ volume precisely because the arbitrage is still open — so low volume is not evidence against a product, it is the signal.

So TikTok US stays the demand signal, and NZ SERP becomes the supply check. The kill signal is not low search volume — it is generic imported listings already ranking in NZ, which means someone has already run the play.

VerdictMeaningResult
GREENno NZ sellers rankingwindow open
AMBERNZ specialty retailers onlycontested, still viable
REDmajor NZ retailer, or ≥2 generic-import listingsplay already run — kill

Run live on the non-electronic shortlist — 11 checks, 6 cents of DataForSEO:

CandidateNZ sellersVerdict
wear and go wig1 — wigs.co.nz🟠 thinnest supply tested
glueless wig human hair1 — wigs.co.nz🟠 thin
hd lace front wig5 specialty🟠 contested
hair topper women5 specialty🟠 contested
clip in hair extensions10 specialty🟠 contested
leather crossbody bag14 specialty🟠 crowded
led face maskgeneric imports + Caci, Sephora, Harvey Norman🔴 shut
silk pillowcaseKmart, Peter Alexander, Ecosa🔴 shut
polarized sunglassesRebel Sport, Hunting & Fishing, Specsavers🔴 shut
silk pajamasTrade Me, Papinelle, Peter Alexander🔴 shut
silk sleep maskSephora, Chemist Warehouse🔴 shut

⚠ This result was a FALSE POSITIVE — wigs are out

S6b flagged wear-and-go wigs: 1 NZ seller as the thinnest supply of anything tested. It read as an open window. It was not — the stage matched the keyword, not the market.

The demand driver doesn't exist here. The US lace-front market is largely driven by Black women's haircare. NZ's 2023 Census MELAA group — Middle Eastern, Latin American and African combined — is 92,760 people, 1.9% of the population, and the African subset is a fraction of that.

And the lone "competitor" is a different business. wigs.co.nz is a medical hair-loss retailer — cancer and alopecia, wig-subsidy grants, survivor testimonials — selling at NZ$509–799 synthetic and NZ$1,799–2,599 human hair against a US$106 TikTok product. Different customer, different reason to buy, roughly 20× the price, and a fitting-and-consultation service business that an Instagram-ad funnel cannot serve.

Thin supply because the market is not worth serving, not because nobody got there yet. That is the one thing S6b cannot see on its own.

The fix — a demand-driver check at the human gate

This is the fourth variant of the same bug: a WiFi smart lock matched by image, synthetic wigs matched by keyword, cheapest-match treated as equivalent, and now a keyword matched to the wrong market. The TikTok signal carries US population composition with it.

So before trusting any amber, ask: why do Americans buy this, and does that reason exist in New Zealand?

Does not transplant: demographically driven (protective-styling haircare), regulation driven (firearms, supplements), culturally driven (US sports, Thanksgiving), climate driven.
Does transplant: universal-need categories — pets, babies, sleep, fitness, home organisation, kitchen, outdoor.

06 / Stage detailWhat goes in, what comes out

Each stage names its API, its inputs, its outputs and where the result is stored. Amber stages spend money; green stages are logic we own and can build today.

S0

Config

No API
InAPIFY_TOKEN, DATABASE_URL, FX rate, thresholds — MARGIN_MULTIPLE=3.5, KILL_SPEND_USD, KILL_CPA_NZD, REFUND_PROVISION_PCT
Out
Store.env — never committed
S1

Discover

$0.0045/item · 2k ≈ $9

Sweep TikTok Shop US by category. Runs on Apify's cloud with US proxies — this is why the NZ geo-block is irrelevant. It only ever blocked you, not the pipeline.

APIunseenuser/TikTok-Shop-Scraper — 100% success / 10,197 runs
POST api.apify.com/v2/acts/{actor}/run-sync-get-dataset-items
In category or keyword list · market US · maxItems
Out mode enum shop_search·shop_catalog·product_details·product_reviews·creator_showcase · region US GB ID MY PH SG VN TH DE FR (no NZ) · getRelatedVideosmay return S3's videos itself, collapsing two stages
Storeupsert Product; append ProductSnapshot — never update

The velocity trap

This response is cumulative lifetime units — "12.5k sold" says nothing about the last seven days. There is no trend in this data. Trending is a delta between two snapshots, which is the entire reason S2 exists and why snapshots are append-only.

S2

Velocity

Free · ours

The one piece of genuine IP in the pipeline. Diff our own snapshot history rather than trusting an actor to compute it.

In≥2 ProductSnapshot rows for the same productId
Outunits24h units7d growthPct7d velocityScore
Mathunits7d = snap(t).unitsSoldTotal − snap(t−7d).unitsSoldTotal
RankGrowth % off a low absolute base — not volume. A 50k-unit product is already saturated and its 1688 price is bid up.

Cold start

Day one has no history, so this stage produces nothing until the second run. That is what S2b is for — and it is also why building the store comes before the analysis.

S2b

Cold-start bridge

$0.002 + $0.004 / product

The only actor that keeps its own daily history — so it has a trend on day one, while ours is still building.

APImemo23/tiktok-shop-sales-scraper — 100% success
In product URLs or IDs
Out soldCount (cumulative) unitsSoldInWindow unitsSoldPerDay salesGrowthPercent trendWindowDays firstSeenAtverified live
ProofRanked by cumulative: 136,585 units, 0.3% growth — dead. Ranked by growth: 71 units, 491.7% — just moving. Two different businesses, for 13 cents.
TraptrendWindowDays is capped by their history depth — min 0.9 / mean 5.4 / max 6.9, all first seen within 8 days. Reject rows under 5 days; 491% over 0.9d is noise.
ThenWean off it. lurkapi was the best-fitting actor in this category and went UNDER_MAINTENANCE mid-research. When an actor dies, our snapshot history is the only thing that survives.
S3

Creative capture

Per product

The hook that made the product trend is already public and already proven. Capture it here, while the product URL is in hand — not at S10 when you'd otherwise write ads cold.

APIthenetaji/tiktok-shop-creator-videos-scraper — 100% / 163 runs
In product URL
Out every showcase + affiliate video promoting it — videoUrl creatorName followers views likes
StoreCreative → feeds S10 directly
S4

Shippability filter

Free · kills ~half

A pure text filter that costs nothing and runs before any sourcing spend. Never pay to source something that can't fly.

InProduct.title · category · description
OutshipVerdict: pass | reject + shipReasons[]
RejectsBATTERY — blocked outright (decision, 28 Aug) · liquids & aerosols · oversized · branded or counterfeit-risk · dead-season
Why blockedNZ Post: lithium-metal prohibited; batteries sent alone prohibited; Li-ion in equipment allowed but max 2 batteries / 4 cells PER PARCEL, ≤100Wh, International Express Courier only — not ePacket, ADV550 declaration, and a UN38.3 Test Summary is law from 1 Jan 2026. Margin survived (~50%) — but freight per unit never improves with volume, so it cannot scale.
MeasuredThe naive filter had a 78% false-negative rate — "LED Face Mask", "Massage Gun", "Smart Ring" contain no battery word. Regex now catches coin cells and the electronics vocabulary that hides them.
S5

Reverse-image source

$0.005 / result

This is the bridge. It is the single step that turns "trending" into "sourceable" — everything upstream is signal, everything downstream is commerce.

APIdevcake/scraper-by-image — 100% / 11,911 runs
In Product.imageUrl
Out 30 matches, 50+ fieldsprice_min price_max moq sold_90d month_sold years_as_gold_supplier factory_inspected delivery_hours service_score
Gotchasprovider takes one value per run — all three platforms = 3 runs, 3× cost. maxProducts has a minimum of 30. Matches are a candidate set, not an identification — an LED-strip image also returned car ambient lights, so a relevance filter belongs before S7.
StoreSourceMatch — this returns so much supplier data it may make S6 partly redundant; re-scope S6 to finalists only
S6

Supplier enrichment

$0.005 + $0.003 / product
APIzen-studio/1688-wholesale-scraper — 9 failures / 35,357 runs
In 1688 product URLs from S5
Out tiered wholesale pricing · MOQ · supplier verification · factory stats · dropship channels · certifications
StoreSourceMatch — enriched in place
S7

Margin gate

FX only

The gate is a number, not an availability check. Something being purchasable is not the same as it being worth buying.

APIFX rate CNY→NZD — still to be chosen. Cache daily; never call per product.
InunitCostCny · FX · freight/unit · target sell price · NZ GST 15% · Meta CAC estimate · refund provision
OutlandedCostNzd netMarginNzd marginPct marginVerdict
Mathnet = sellNzd/1.15 − landedCost − metaCac − (sellNzd × refundProvision)
Kill US retail price FLOOR — applied before the growth ranking. Freight and CAC are near-fixed per sale, so a cheap product cannot carry them — see §01–03.
At 500g (freight NZ$15.39, CAC NZ$12): break-even US$22.75, 25% net at US$33.00.
Working rule: US retail ≥ US$30 AND under 500g. Heavy or cheap is dead however well it trends.
NoteCAC and freight are estimates until the first real campaign — the table moves with them, but the shape holds.
S8

Human gate

Greg · weekly

One list, once a week. Nothing past this point is free — this is the last stop before ad spend.

InCandidate where status = pending, ranked by velocityScore
Outstatus → approved | rejected · decidedAt · decidedNote
S9

Landing page

Shopify Admin API
APIShopify Admin API (product + page create), or SettledLoop for a single-product funnel
Inapproved Candidate + Creative
Outlive URL
MustHonest delivery ETA on the page. This is the model (a) tax — skipping it converts into chargebacks, not sales.
S10

Meta ads

Meta Marketing API
APIMeta Marketing API — campaign / adset / ad create
InLP URL + Creative from S3
Outcampaign + ad IDs
Reusemeta-ads · meta-creative-engine · meta-ads-copy skills already exist — assembly, not greenfield
S11

Monitor

Meta Insights + Shopify Orders
APIMeta Insights (spend, CPA) + Shopify Orders (actual sales)
Incampaign IDs · KILL_SPEND_USD · KILL_CPA_NZD
Outcontinue | kill

Kill criteria set before spend

"Monitor" is not a stage until it carries a number. Kill at $X spend with zero purchases, or CPA > $Y. Without thresholds fixed in advance, monitoring is just watching it bleed.

S12

Scale

Decision

Winners only — and this is where the model (b) question returns. Pre-buying a validated winner into NZ stock cuts delivery to three days and lifts conversion, but that is a capital decision taken per product, on evidence, not a strategy switch.

07 / InventoryEvery API, and what's blocking it

APIStagesAuthStatus
Apify — 5 actorsS1 · S2b · S3 · S5 · S6APIFY_TOKENNo token — hard blocker
FX rate CNY→NZDS7tbdNot chosen
Shopify AdminS9 · S11store tokenAvailable — Coy precedent
Meta Marketing + InsightsS10 · S11existing accessAvailable

The only hard blocker

The Apify token. Everything at S2, S4, S7 and S8 is internal logic that can be built and tested against fixtures right now — that is a third of the pipeline, and the third that holds the actual IP.