Devex Jobs Scraper — NGO & International Development Jobs
Pricing
Pay per event
Devex Jobs Scraper — NGO & International Development Jobs
Scrape international-development, NGO, humanitarian and UN jobs from Devex.com — donor-funded programmes, consultancies, INGO and multilateral roles. An AI step (bring your own Anthropic or Mistral key) returns clean records: title, organisation, location, salary, deadline, URL.
Scrape international-development, NGO, humanitarian and UN vacancies from Devex.com, parsed by an AI extraction step (BYO Anthropic or Mistral key). Up to 17 structured fields per posting, a delta/monitoring mode that pays only for genuinely new jobs, and an alive-check mode to re-verify known postings.
Bring your own key. This Actor uses either Claude (Anthropic) or Mistral for AI discovery/extraction — pick with
provider, or just supply whichever key you have (the Actor auto-selects the matching provider whenprovideris left unset). PassanthropicApiKey(provider"anthropic", default) ormistralApiKey(provider"mistral") in the input. Without a matching key the run still succeeds — it produces a single dataset row explaining how to supply a key, instead of failing.
AI provider: Anthropic vs Mistral
provider selects which AI does discovery + extraction:
anthropic(default) — a Claude agent uses Anthropic's built-in web-search tool to search Devex via Google site-search and extract structured listings from the same tool loop.mistral— since Mistral has no built-in web-search tool, this path uses keenable (no-auth web search) to run the same Google site-searches, then ONE Mistral call extracts structured fields from the combined candidate list (title/URL/snippet — Devex blocks direct page fetches for both providers, so both work from search-result metadata only, never a page fetch).
Pick whichever provider you'd rather bring a key for; output shape and the no-guessing extraction rules (never fabricate postedAt/deadline, extract company from explicit signals only) are identical either way.
What Devex jobs data does this scraper extract?
Each result is one flat JSON record per job posting:
| Field | Meaning |
|---|---|
source | Always "devex" |
id | Stable source-side identifier (job id parsed from the posting URL) |
title | Job title as posted |
company | Hiring company / organisation |
location | Location / duty station text from the search snippet (may be empty) |
url | Direct link to the posting |
postedAt | Posting date (YYYY-MM-DD), only when explicitly stated on the page or search snippet — null when unknown. Devex postings are discovered via Google search results, which frequently omit a reliable date, so null is common and expected; the actor never guesses or fabricates a date. |
deadline | Application closing date (YYYY-MM-DD), only when explicitly stated — null when not stated. Also commonly null. |
salary | Pay / day-rate exactly as stated (e.g. USD 90,000–110,000) — null when not stated, never guessed. |
contractType | Engagement type when stated: full-time, part-time, contract, permanent, temporary, internship, consultancy, or volunteer — null when unclear. |
workplace | on-site, hybrid, or remote when stated — null when unclear. |
employerWebsite | Hiring organisation's website or Devex profile URL when present in the snippet/URL — null otherwise, never fabricated. |
snippet | Short description excerpt from the search result |
isNew | Only in delta mode (onlyNewSinceLastRun): always true, marking a posting not delivered on a prior delta run. |
isActive | Only in alive-check mode (jobUrls): true if the posting still appears open, false if closed/expired, null if undeterminable. |
checkedAt | Only in alive-check mode: ISO 8601 UTC timestamp of the liveness check. |
externalId is also present on every record, duplicating id — it is a deprecated alias kept for backward compatibility with existing integrations and will be removed in a future major version.
How to scrape Devex jobs with this Actor
- Click Try for free / Run — no login to the target site, no cookies, no proxies to configure.
- Adjust the input (keyword, filters,
maxItems) or keep the defaults. - Run it and export the dataset as JSON, CSV or Excel, or read it over the API.
Run it from your own code:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("nomad-agent/devex-scraper").call(run_input={"maxItems": 50})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["title"], "—", item["company"], item["url"])
Or a single HTTP call that runs the Actor and returns items in one response:
curl -X POST \"https://api.apify.com/v2/acts/nomad-agent~devex-scraper/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \-H "Content-Type: application/json" \-d '{"maxItems": 50}'
Integrations
Export the dataset as JSON, CSV or Excel from the Apify Console, pull it over the API (including run-sync-get-dataset-items for a single-call run), wire it into Make/Zapier/n8n, or call this Actor as a tool from an AI agent via the Apify MCP server.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
provider | string | "anthropic" | Which AI provider runs discovery + extraction: "anthropic" (Claude + built-in web search) or "mistral" (keenable web search + Mistral extraction). |
anthropicApiKey | string | — | Your Anthropic API key (sk-ant-...). Required when provider is "anthropic" — your key is billed directly by Anthropic for that usage (separate from Apify's pricing). Keep this secret. |
mistralApiKey | string | — | Your Mistral API key. Required when provider is "mistral" — used only for extraction (search itself goes through keenable, no key needed). Billed directly by Mistral, separate from Apify's pricing. Keep this secret. |
mistralModel (Advanced) | string | "mistral-small-latest" | Mistral model for extraction (provider "mistral" only): mistral-small-latest (default — matches larger models on this small, well-scoped task), mistral-medium-latest, or mistral-large-latest. |
keyword | string | "" | Topic or role keyword to focus the search (e.g. "monitoring evaluation", "migration", "policy analyst"). Leave empty to surface a broad mix of international-development postings. |
location | string | "" | Geographic filter passed to the search (e.g. "Geneva", "remote", "Africa"). Leave empty for worldwide listings. |
contractType | string | "" (Any) | Only return postings of this engagement type (full-time, part-time, contract, permanent, temporary, internship, consultancy, volunteer). Applied by the AI as a search constraint, not a post-hoc regex. |
workplace | string | "" (Any) | Only return postings with this workplace type (on-site, hybrid, remote). Applied by the AI as a search constraint. |
onlyNewSinceLastRun | boolean | false | Delta / monitoring mode — output only postings not seen on a previous run with this flag on. See Delta mode / monitoring below. |
jobUrls | array | [] | Alive-check mode — provide known Devex job URLs to re-verify whether each is still open (returns isActive per URL). When set, discovery is skipped. See Alive-check mode below. |
maxItems | integer | 12 | Maximum number of job postings to return (1–50). In alive-check mode it also caps how many jobUrls are checked. Each result is billed under this Actor's pay-per-result pricing; the AI API calls behind every run are ALSO billed separately by your provider, regardless of this cap. |
model (Advanced) | string | "claude-haiku-4-5-20251001" | Anthropic model to use for job discovery. Must support the web_search_20250305 built-in tool (Claude 3.5 Sonnet or later recommended). The default works well for almost everyone. |
proxyConfiguration (Advanced) | object | Apify Proxy | Reserved for parity / forward-compatibility. Discovery runs server-side inside the AI provider or keenable, neither of which routes through an Apify proxy, so this setting is currently inert. |
Output example
postedAt and deadline are null unless Devex's search results genuinely state a date — that's the honest common case, not a bug:
{"source": "devex","id": "889021","externalId": "889021","title": "Chief of Party — USAID Health","company": "Chemonics","location": "Nairobi, Kenya","url": "https://www.devex.com/jobs/chief-of-party-889021","postedAt": null,"deadline": null,"salary": null,"contractType": "full-time","workplace": null,"employerWebsite": null,"snippet": "Chemonics seeks a Chief of Party..."}
When a date, salary, or workplace is stated on the page or in the search snippet, the matching field is populated as a string instead of null.
Delta mode / monitoring
Set onlyNewSinceLastRun: true to run this Actor on a schedule and pay only for genuinely new Devex postings. The Actor remembers every posting id it has delivered in a dedicated per-Actor key-value store; on the next delta run, already-seen postings are dropped before they are pushed or billed. New postings carry "isNew": true.
- The first delta run has nothing to compare against, so it emits everything and seeds the state.
- State is best-effort: if the state store can't be read, the run safely treats everything as new rather than failing.
- Combine with
keyword/location/contractType/workplaceto monitor a specific slice (e.g. new remote M&E consultancies) cheaply on a cron schedule.
Alive-check mode
Pass a list of known Devex job URLs in jobUrls to re-verify whether each posting is still open — useful for keeping an existing pipeline/ATS free of dead links. When jobUrls is set, the Actor skips keyword/location discovery and returns one row per URL with:
isActive:true(still open),false(closed/expired/removed), ornull(could not be determined).checkedAt: ISO 8601 UTC timestamp of the check.
Because Devex blocks direct page fetches, liveness is judged from live web-search signals rather than a page load, so null is returned honestly when the signal is ambiguous rather than guessing.
Pricing
Pay per event: $0.005 per Actor start and $0.003 per job returned. 100 jobs ≈ $0.305. No subscription, no rental — you pay only for what you fetch.
This is a "bring your own key" (BYOK) Actor. Every run calls the AI provider you pick (provider) using the anthropicApiKey or mistralApiKey you supply, and that usage is billed to your own Anthropic or Mistral account, separately from Apify's pricing above. Apify's PPE charges only cover the Actor's own run/result events — they do not include Anthropic's or Mistral's token costs. Check Anthropic's pricing or Mistral's pricing for the model you configure.
Use cases
- Development-sector job boards
- Proposal/recruitment teams tracking donor-funded roles
- Consultant roster building
- Aid-sector hiring analysis
FAQ
Is it legal to scrape Devex jobs? This Actor reads only publicly available job postings — data any visitor can see without logging in. No personal data behind authentication is touched. Review the target site's terms and your local regulations for your specific use case.
Do I need an account on the target site? No. Postings are fetched from public pages/APIs — no login, cookies or session tokens.
How fresh is the data? Every run performs live Claude web searches against Devex's Google-indexed listings at run time — there is no caching layer, so each run reflects whatever is currently indexed.
How many jobs can I get?
maxItems caps the run at 1–50 postings.
Something broken or missing? Open an issue on the Actor's Issues tab — it is monitored and reliability fixes ship fast.
Related Actors
- UNjobs Scraper — unjobs.org UN Vacancies
- Research & Academic Jobs Scraper — 10 Sources
- UN Careers Job Scraper — United Nations Jobs
- ReliefWeb Jobs Scraper — Humanitarian & NGO
- Impactpool Jobs Scraper — UN & NGO Careers
From the maker of Oink — an open-source, AI-powered job-search bot for Telegram that runs on these Actors. Try the free bot, get a managed instance at oinkjobsearch.com, or browse the full catalog of 50+ Actors.