Quick answer
importyeti.com's public search API exposes a shipment-date field formatted DD/MM/YYYY — not the US-standard MM/DD/YYYY you'd naturally assume on a site that only covers US Customs filings. Parse it with the wrong format string and every date for the first 12 days of a month silently swaps month and day. The ImportYeti Alternative Scraper parses it correctly, confirmed against the live wire format, and returns 15 typed fields per matched importer or supplier at $0.005 per row plus a $0.005 run-start charge — $5.005 for 1,000 rows.
The date bug that only shows up half the time 🗓️
This is the kind of bug that survives code review, because it doesn't fail loudly — it fails quietly, on some rows.
ImportYeti's /api/search endpoint returns a mostRecentShipment field as a plain string like "15/07/2026". If you're a US-focused team scraping a US Customs data source, the reasonable-looking assumption is MM/DD/YYYY. For that string, strptime("15/07/2026", "%m/%d/%Y") throws immediately — day 15 isn't a valid month, so at least you find out. But for "03/07/2026", the wrong format string doesn't throw. It happily parses to March 7th when the real date is July 3rd. No exception, no warning, just a wrong date sitting in your dataset looking exactly as valid as the correct ones.
We confirmed the actual format live against the API — it's DD/MM/YYYY — and parse against that. When a value doesn't match even that format, we log a warning and null the field rather than guess. most_recent_shipment_date in the output is either a correct ISO date or null; it's never a plausible-looking wrong one.
What else the live API doesn't tell you upfront 🔧
A few more things we only know because we captured the live wire format rather than guessing from the rendered page.
The query parameter has to be q. query and search both return a stripped-down envelope with fewer fields. q returns the richest one — the one with totalShipments, otherAddressesCount, and the rest of the profile data this Actor's output depends on.
Pagination is 1-indexed, confirmed by a live cloud run where a 15-result request returned ranks 1 through 15, with results 11–15 sourced from page=2 — meaning page 1 is a real, distinct page and starting your loop at page=0 gets you nothing extra, just a wasted request.
country has no source field. The search envelope carries countryCode (ISO-3166-1 alpha-2) but never a full country name. Rather than reverse-mapping a code to a name with our own lookup table and risking a mismatch, country ships as null and country_code carries the verified value.
The API tells you your own rate-limit budget, in-band. A requestLimitRemaining counter rides inside the JSON response body itself — not a header — starting around 24 and counting down. We treat a low remaining budget the same way we'd treat an approaching 429: pause, rotate session and browser fingerprint, and resume, instead of waiting to actually get blocked.
What we handle for you 🛡️
-
Residential proxy by default, not opt-in. importyeti.com issues Cloudflare managed challenges to flagged datacenter IPs on every probed path — this is the one Actor in our fleet where
RESIDENTIALships as the default proxy group instead of something you have to turn on. -
We detect the challenge two ways — a
cf-mitigated: challengeresponse header, or a"Just a moment"body marker as a fallback — and rotate to a fresh session and browser profile before retrying, rather than treating a 200-with-challenge-page as real data. -
We retry with exponential backoff on
408 / 429 / 5xx, up to 5 attempts, honoringRetry-After. -
We rotate browser fingerprints across Chrome, Firefox, and Safari TLS impersonation profiles via
curl-cffi— header-only spoofing doesn't survive Cloudflare's fingerprinting, so we don't rely on it. - We deduplicate by URL slug. The same company matched by two different search queries is written and charged once, not twice.
- You pay only for results that hit your dataset. No data, no charge, beyond the small run-start warm-up fee.
Full output schema 📦
Fifteen fields per matched company row:
| Field | Type | Notes |
|---|---|---|
company_name |
string | Legal name from US Customs filings |
company_type |
enum |
importer (US consignee) or supplier (foreign shipper) |
country |
string | null | No source field in the live envelope — always null |
country_code |
string \ | null |
address |
string | null | Most recent customs record address |
total_shipments |
int | null | Total bill-of-lading count on file |
most_recent_shipment_date |
string \ | null |
other_addresses_count |
int | null | Distinct alternative addresses on file |
other_names_count |
int | null | Distinct alternative names (DBAs, subsidiaries) |
trademarks |
list[string] | Linked brand names |
profile_url |
string | Canonical `importyeti.com/company\ |
{% raw %}slug
|
string | URL slug — dedup key |
source_query |
string | null | Which search query matched, in search mode |
rank |
int | null | Position in the search-API ranking (1 = top) |
scraped_at |
string | ISO 8601 UTC |
Who this is for
Sales prospecting — build a list of US importers already shipping a competitor's product category, ranked by shipment volume via total_shipments.
Sourcing research — find foreign suppliers already shipping into the US for a given product before cold-emailing a trade show floor.
M&A and supply-chain diligence — sanity-check a target company's declared trade volume and country exposure in minutes. trademarks pairs well with a targeted pull from our USPTO Trademark Scraper when you need to verify brand ownership too.
Frequently asked questions
Is this the same data as ImportYeti, Panjiva, or ImportGenius?
It's a self-serve wrapper around importyeti.com's own keyless JSON search — the same underlying US Customs bill-of-lading data those $99–$399+/mo subscription tools charge for, aggregated into company/supplier trade-profile rollups, not per-shipment line items.
Why is most_recent_shipment_date sometimes null?
Only when the raw value doesn't match the confirmed DD/MM/YYYY format. We log the malformed value and null the field rather than fabricate a date.
Does it need residential proxies to work?
Yes, and it's on by default for this Actor specifically — importyeti.com has confirmed Cloudflare managed-challenges on datacenter IPs across every probed path.
What does 2,000 matched rows cost?
$10.005 — 2,000 × $0.005, plus the $0.005 run-start charge.
Can I get individual per-shipment records (date, HS code, weight, port)?
Not in v1. Those live behind importyeti.com's login/bot-gated profile pages. This Actor covers the public rollup data — shipment counts and most-recent activity, not line-item filings.
Try it
Live on the Apify Store: ImportYeti Alternative Scraper.
Feed it company names, product keywords, or direct profile URLs — it resolves each to a matched, deduplicated trade-profile row. Pay-per-event, no subscription.
Built by Devil Scrapes — we build scrapers for the targets that fight back.
Top comments (0)