Search "remote data analyst" and half the results are "Remote – US only", "must reside in Germany", or hybrid with a hidden office. If you live in Brazil, Mexico or Costa Rica, you can lose an evening opening postings you're not allowed to apply for.

This post shows a Python script that returns remote jobs filtered by where you're allowed to work from: country, region and time-zone overlap. It writes a CSV with the eligible countries for each job so you can check at a glance.

What you need

  • Python 3.9+, pip install apify-client (v3)
  • An Apify account (free plan includes $5/month of usage) and your API token

The jobs come from the Remote Jobs API Actor, which reads postings straight from company career sites (Greenhouse, Lever, Ashby, Workable, Workday and others) and classifies each one: how remote it is, which countries or regions are eligible, and the UTC offsets that implies.

The script

import csv, os from apify_client import ApifyClient client = ApifyClient(os.environ["APIFY_TOKEN"]) run = client.actor("steady-scrape/remote-jobs-api").call(logger=None, run_input={ "keywords": ["data analyst", "analytics engineer"], "regions": ["Latin America"], # or "workerCountries": ["BR", "MX"]  "remoteTypes": ["FULLY_REMOTE", "REMOTE_OPTIONAL"], "minConfidence": "medium", "postedWithinDays": 14, "maxResults": 20, }) jobs = list(client.dataset(run.default_dataset_id).iterate_items()) with open("remote_jobs.csv", "w", newline="") as f: w = csv.writer(f) w.writerow(["company", "title", "scope", "eligible", "utc_range", "confidence", "posted", "url"]) for j in jobs: eligible = ", ".join(j.get("eligibleCountryNames") or j.get("eligibleRegions") or ["worldwide"]) utc = f'{j["utcOffsetMin"]}..{j["utcOffsetMax"]}' if j.get("utcOffsetMin") is not None else "" w.writerow([j["company"], j["title"], j["remoteScope"], eligible, utc, j["remoteConfidence"], (j.get("postedAt") or "")[:10], j["jobUrl"]]) print(f'{j["company"][:14]:<14} {j["title"][:44]:<44} {j["remoteScope"]:<9} {eligible[:30]}') 

The filters that matter:

  • regions: one or more of North America, Latin America, Europe, Middle East & Africa, Asia Pacific.
  • workerCountries: ISO codes or names ("BR", "Mexico", "EU"). Worldwide jobs and jobs open to your region are included.
  • workerTimezone + maxTimezoneDiffHours: e.g. "America/Costa_Rica" and 3 keeps jobs whose working hours overlap yours, even if they don't name your country.
  • remoteTypes: drop REMOTE_OPTIONAL if you only want fully remote. HYBRID is off by default.
  • minConfidence: high means the career site's remote flag and the location text agree. medium is one clear signal.

Real output (Latin America, last 14 days)

I ran this for "data analyst" and "analytics engineer" on Nov 1, 2026. 20 jobs came back in 5.7 seconds. A sample:

company title eligible UTC
LawnStarter Analytics Engineering Manager, Data Platform Mexico, Brazil −8..−5
DoiT Analytics Engineer Latin America −6..−3
truelogic Senior Full-Stack Growth Engineer – Marketing & Analytics Mexico, Panama, Brazil, Peru, Colombia, Uruguay −8..−5
Wellhub Marketing Analytics Engineer Brazil −5..−2
Zipdev Report Writer / Data Analyst (Sigma) Mexico −8..−5
assurant Lead Reinsurance Data Analyst Argentina −3
viatris Financial Master Data Analyst Costa Rica −6
kraken.com Sr. Data Analyst, Compliance Canada, Brazil −8..−2
StartupBlink Data Analyst worldwide —

Of the 20: 13 named specific countries, 2 named a region and 5 were open worldwide. 19 were high confidence. They came from Workday (6), Lever (4), Workable, Greenhouse and Ashby (3 each) and Breezy (1).

What it cost

At the free-plan list price: 20 jobs × $0.0015 + $0.00005 Actor start = about $0.03. maxResults is a hard cap, so you can't overspend on a broad keyword.

Run it daily for only new jobs

Add these to run_input and schedule the script (cron, GitHub Actions or an Apify schedule):

"onlyNewSinceLastRun": True, "firstRunEmitsAll": False, # first run records a free baseline "stateKey": "latam-data-jobs", 

After the first run you're only billed for postings you haven't seen before.

Tips

  • Many postings just say "Remote" without saying where. They're excluded when you filter by country/region/time zone. Set includeUnspecifiedEligibility: True to include them, then read the description.
  • remoteEvidence on each job quotes the text the classification is based on. Check it before you apply.
  • mergedPostings shows when the same job was posted for several countries and merged into one row.

Disclosure: SteadyScrape publishes the Actor used in this post. Results are from a real run on Nov 1, 2026; job boards change daily.