Djinni Jobs Scraper
Pricing
from $0.79 / 1,000 job scrapeds
Djinni Jobs Scraper
Scrape tech job listings from Djinni.co by keyword, location, experience, English level, and remote status. Get titles, companies, salaries, descriptions, and required skills, with incremental change monitoring. Export as JSON, CSV, or Excel.
Pricing
from $0.79 / 1,000 job scrapeds
Rating
0.0
(0)
Developer
ParseBird
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Djinni Jobs Scraper
Scrape tech job listings from Djinni.co — the largest job board for developers, QA, designers, and IT specialists in Ukraine and Eastern Europe — into clean, structured JSON. The Djinni Jobs Scraper pulls the job title, company, full description, salary, required experience, English level, industry, remote status, and view and application counts from any keyword search, with no login and no Djinni API.
| Search Djinni by keyword, then filter by location, years of experience, English level, remote status, salary, company, and domain — get 40+ structured fields per job, the full description in text, HTML, and Markdown, and incremental change monitoring for scheduled runs. |
Copy to your AI assistant
Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.
Actor: parsebird/djinni-jobs-scraper (Apify). Scrapes tech jobs from djinni.co. Call with ApifyClient.Input JSON fields:query: string[] - keyword(s) to search, e.g. ["python","golang"]. Empty = browse all tech jobs.location: string[] - city/country/region kept if the listing location text matches (post-fetch)startUrls: string[] - Djinni search URLs (https://djinni.co/jobs/keyword-python/) or job URLs (https://djinni.co/jobs/820617-.../)experienceLevel: string[] - keep listings asking exactly N years, values "0".."10" (post-fetch)englishLevel: string[] - CEFR levels A1,A2,B1,B2,C1,C2 (post-fetch)isRemote: bool (default false) - keep full-remote listings onlyemploymentType: string[] - FULL_TIME, PART_TIME (post-fetch)companyName: string[] / domain: string[] - substring filters on company / industry (post-fetch)salaryFrom / salaryTo: int USD - drop listings whose published salary range is out of bounds; 0 = offpostedWithinDays: int - freshness filter; 0 = any ageincludeKeywords / excludeKeywords: { keywords: string[], matchTitle: bool, matchDescription: bool }scrapeDetails: bool (default false) - open each job page for required languages, required skills, company profile URLcompact: bool (default false) - core fields only, for LLM/agent pipelinesmaxResults: int (default 25) - primary cost cap; billed rows. 0 = unlimitedmaxPages: int (default 5) - max search pages per query (15 jobs/page)incrementalMode: bool + stateKey: string - emit only NEW/UPDATED/REAPPEARED jobs vs the last runemitUnchanged / emitExpired / skipReposts: bool - monitoring row togglesproxyConfiguration: { "useApifyProxy": true }Output: one dataset item per job - jobKey, title, company, companyUrl, companyLogo, location, description,descriptionHtml, descriptionMarkdown, salaryText, salaryMin, salaryMax, salaryCurrency, employmentType,industry, category, experienceMonths, experienceYears, englishLevel, requiredLanguages, requiredSkills,isRemote, remoteText, directApply, postedAt, validThrough, viewsCount, applicationsCount, canonicalUrl,contentHash, changeType, firstSeenAt, lastSeenAt, isRepost.Example: { "query": ["python"], "maxResults": 50 }API: https://api.apify.com/v2/acts/parsebird~djinni-jobs-scraper · Token: https://console.apify.com/account/integrations
What does Djinni Jobs Scraper do?
Djinni is where thousands of product companies, outsourcers, and startups post remote and on-site tech roles — Python, JavaScript, Go, Java, .NET, QA, DevOps, data, design, and management. There is no public Djinni API — this Djinni scraper is the alternative. It extracts:
- 💼 Job basics — title, hiring company, company logo, company website, company type (Product, Outsource, Agency), and the job's own Djinni URL.
- 📝 Full description — the complete job posting in plain text, original HTML, and Markdown, plus a character count.
- 💰 Salary — the relative salary marker (
$to$$$$) shown on the card, and the exactsalaryMin/salaryMax/ currency when the company publishes a range. - 📈 Requirements — years of experience (as months and years), the CEFR English level (B2, C1, …), and — with
scrapeDetails— the full required-languages list and the required-skills experience breakdown. - 🌍 Location & remote — the applicant location text, the applicant region and country from the structured data, and a
full remote/office/hybridclassification. - 🏭 Context — the industry / domain (fintech, gamedev, gambling, healthcare), employment type, "actively hiring" and "confirmed hires" flags, and live view and application counts.
- 🔁 Change tracking — incremental mode tags every row
NEW,UPDATED,UNCHANGED,REAPPEARED, orEXPIREDand detects reposts of expired listings.
Common uses: building a tech-jobs aggregator, tracking hiring demand by stack or seniority, salary benchmarking for Eastern Europe, sourcing companies that hire remotely, and feeding a job-alert or LLM pipeline.
Input parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| query | array of strings | No | ["python"] | Keyword(s) to search. Each entry runs its own search. Empty browses all jobs. |
| location | array of strings | No | — | City / country / region kept if the listing location matches. Applied after fetching. |
| startUrls | array of strings | No | — | Djinni search URLs or job detail URLs. Scraped in addition to query. |
| experienceLevel | array of strings | No | — | Keep listings asking exactly N years (0–10). Applied after fetching. |
| englishLevel | array of strings | No | — | Keep listings requiring one of these CEFR levels (A1–C2). Applied after fetching. |
| isRemote | boolean | No | false | Keep full-remote listings only; drop office and hybrid roles. |
| employmentType | array of strings | No | — | Keep FULL_TIME and/or PART_TIME listings. |
| companyName | array of strings | No | — | Keep listings whose company name contains one of these values. |
| domain | array of strings | No | — | Keep listings whose industry / category contains one of these values. |
| salaryFrom / salaryTo | integer | No | 0 | Drop listings whose published salary range is out of bounds (USD). 0 disables. |
| postedWithinDays | integer | No | 0 | Keep listings published within N days. 0 allows any age. |
| includeKeywords | object | No | — | { "keywords": ["react","node"], "matchTitle": true, "matchDescription": true } — require at least one. |
| excludeKeywords | object | No | — | Same shape — drop listings that contain any. |
| scrapeDetails | boolean | No | false | Open every job page for the required-languages list, required-skills experience, and company profile URL. |
| compact | boolean | No | false | Return only core fields, for LLM / AI-agent pipelines. |
| maxResults | integer | No | 25 | Maximum job listings to return. Primary cost control — billed rows. 0 = unlimited. |
| maxPages | integer | No | 5 | Maximum search pages per query (15 jobs per page). |
| incrementalMode | boolean | No | false | Return only jobs that are new or changed since the last run with the same stateKey. |
| stateKey | string | No | default | Separates one watchlist or schedule from another. |
| emitUnchanged / emitExpired / skipReposts | boolean | No | false | Monitoring row toggles. |
| proxyConfiguration | object | No | Apify Proxy | Proxy settings. Djinni works over automatic Apify Proxy. |
Example inputs
Basic search — keyword-driven search with a result cap:
{ "query": ["python"], "maxResults": 50 }
Filtered search — senior remote roles with strong English:
{"query": ["golang", "rust"],"isRemote": true,"experienceLevel": ["5", "6", "7"],"englishLevel": ["B2", "C1", "C2"],"maxResults": 100}
Incremental tracking — only emit jobs that changed since the previous run:
{"query": ["python"],"maxResults": 200,"incrementalMode": true,"stateKey": "python-tracker"}
Compact filtered output — lightweight records for an AI agent or MCP data source:
{"query": ["devops"],"experienceLevel": ["3"],"maxResults": 50,"compact": true}
Direct URLs:
{"startUrls": ["https://djinni.co/jobs/keyword-java/","https://djinni.co/jobs/820617-senior-python-engineer/"],"maxResults": 100}
What data can you extract from Djinni?
| Field | Description |
|---|---|
| jobKey | Djinni numeric job id |
| jobId | Stable hash of the canonical job URL |
| title | Job title |
| company | Hiring company name |
| companyUrl | Company website |
| companyLogo | Company logo image URL |
| companyType | Product, Outsource, Outstaff, Agency, Startup |
| location | Applicant location text, e.g. "Countries of Europe or Ukraine" |
| applicantRegion / applicantCountry | Region and country from the structured data |
| description / descriptionText | Full job description as plain text |
| descriptionHtml / descriptionMarkdown | Full description as HTML and Markdown |
| salaryText | Relative salary marker ($–$$$$) shown on the card |
| salaryMin / salaryMax / salaryCurrency / salaryPeriod | Exact published salary range, when the company provides one |
| employmentType | FULL_TIME or PART_TIME |
| industry / category | Domain (fintech, gamedev, …) and Djinni skill category |
| experienceMonths / experienceYears | Required experience |
| englishLevel | Required CEFR English level (A1–C2) |
| requiredLanguages / requiredSkills | Full language and skill-experience list (with scrapeDetails) |
| isRemote / remoteText / jobLocationType | Remote classification and wording |
| directApply | Whether the listing accepts direct applications |
| activelyHiring / companyConfirmedHires | Djinni trust and activity badges |
| postedAt / postedAtRaw / validThrough | Publish timestamp and expiry |
| viewsCount / applicationsCount | Live engagement counts |
| canonicalUrl | The job's page on Djinni |
| extractedUrls / socialProfiles | Links found in the description |
| changeType / firstSeenAt / lastSeenAt / isRepost / repostOfId | Incremental monitoring fields |
Output example
{"jobKey": "846430","title": "Python Backend Developer","company": "Zutobi","companyUrl": "https://zutobi.com/us","companyLogo": "https://p.djinni.co/41/eb2244c706b2fa4a1cc0776c9b1ade/zutobi-dou-1_400.png","companyType": "Product","location": "Countries of Europe or Ukraine","applicantRegion": "Europe","description": "Zutobi is a global edtech product company ...","descriptionMarkdown": "Zutobi is a global edtech product company ...","descriptionLength": 2126,"salaryText": "$$$","salaryMin": null,"salaryMax": null,"employmentType": "FULL_TIME","industry": "edutech","category": "Python","experienceMonths": 36,"experienceYears": 3,"englishLevel": "B2","requiredLanguages": [{ "language": "English", "level": "B2", "levelText": "B2 - Upper Intermediate" },{ "language": "Ukrainian", "level": "B2", "levelText": "B2 - Upper Intermediate" }],"isRemote": true,"remoteText": "Full Remote","directApply": true,"activelyHiring": false,"companyConfirmedHires": true,"postedAt": "2026-09-03T13:30:26.792615","validThrough": "2026-10-03T13:30:26.792615","viewsCount": 19,"applicationsCount": 9,"canonicalUrl": "https://djinni.co/jobs/846430-python-backend-developer/","sourceDomain": "djinni.co","sourceCountry": "UA","searchQuery": "python","detailFetched": true,"contentQuality": "full","contentHash": "60b11d9eabd65f44290c98061352065ea4e74894863afd05a850105903ae5d4a","changeType": "NEW","firstSeenAt": "2026-09-03T10:00:00.000Z","lastSeenAt": "2026-09-03T10:00:00.000Z"}
Download the dataset as JSON, CSV, Excel, HTML, or XML from the Storage tab or the Apify API.
Use cases
- Tech-jobs aggregator — feed a job board or a Telegram / Slack alert channel with fresh Djinni roles.
- Hiring-demand tracking — measure how many jobs open per stack, seniority, or domain over time with incremental mode.
- Salary benchmarking — collect published salary ranges for Eastern Europe by role and experience.
- Remote-friendly company lists — pull companies posting full-remote roles in a given field.
- Recruiting & sourcing — monitor competitors' openings and spot companies scaling a team.
- LLM & AI agents — compact, structured job records for retrieval, summarisation, or matching.
How it works
- Build the search — each
querybecomes a Djinni keyword search; an empty query browses all jobs.startUrlsare added as-is. - Read the results — every search-results page carries both a structured
JobPostingblock and the visible cards; the actor merges them per listing, so the full description, salary, experience, and English level come straight from the search page — no extra request per job. - Enrich (optional) — with
scrapeDetails, each job page is opened for the required-languages list, required-skills experience, and company profile URL. - Filter — location, experience, English level, remote, employment type, company, domain, salary, freshness, and include / exclude keyword rules are applied to the collected jobs.
- Detect changes (optional) — in incremental mode the run is compared with the previous run for the same
stateKey, and only the selected transitions become dataset rows. - Rows stream to the dataset and stop at
maxResults.
How much does it cost to scrape Djinni?
This actor is pay per result — charged once per job saved.
| Plan | Price per 1,000 jobs |
|---|---|
| Free | $0.99 |
| Bronze | $0.89 |
| Silver | $0.89 |
| Gold | $0.79 |
A small platform Actor start fee also applies per run. maxResults is the exact number of billed rows. Scraping 1,000 jobs on the Free plan costs about $0.99. Apify's monthly free platform usage covers small runs. In incremental mode you are billed only for the change rows that are emitted, not for the full search.
How to scrape Djinni
- Click Try for free and sign in to Apify.
- Enter one or more keywords (or leave
queryempty to browse all jobs). - Add any filters — location, experience, English level, remote, salary.
- Set maxResults (start low, e.g. 25).
- Click Start, then watch rows appear in the Output tab.
- Export from Storage, or pull results via the API.
Run it via API
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("parsebird/djinni-jobs-scraper").call(run_input={"query": ["python", "golang"],"isRemote": True,"maxResults": 100,})for job in client.dataset(run["defaultDatasetId"]).iterate_items():print(job["title"], "-", job["company"], "-", job.get("salaryText"))
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('parsebird/djinni-jobs-scraper').call({query: ['devops'],experienceLevel: ['3', '4', '5'],maxResults: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Schedule recurring runs, add webhooks, or push results to Google Sheets, Slack, Zapier, and Make with Apify integrations.
FAQ
Do I need a Djinni account or API key? No. The scraper reads public Djinni listing pages only. Djinni has no public jobs API — this actor is the alternative.
How current is the data?
Live. Each run reads Djinni at that moment. Use Apify's scheduler with incrementalMode to keep a dataset fresh and get only what changed.
Why is the full job description already in the results without scrapeDetails?
Djinni's search-results pages embed the complete description for every listing, so the actor gets it in one request per page. Turn on scrapeDetails only for the required-languages list, required-skills experience, and the company profile URL.
How do the experience and English filters work?
They are applied after fetching. experienceLevel keeps listings that ask for exactly that many years; englishLevel matches the CEFR level shown on the listing. Listings that don't state a value are dropped when the matching filter is set.
What does salaryText mean?
Djinni shows a relative marker — $ below average, $$ average, $$$ above average, $$$$ top range — for every job. When a company publishes an actual range, salaryMin, salaryMax, and salaryCurrency are also filled.
What counts as a billed row?
Every job saved to the dataset, including incremental change rows. maxResults is the cap.
Something's not working. Open an issue on the Issues tab with your input and the run link — we respond quickly.
Is it legal to scrape Djinni?
Scraping publicly available pages is legal in most jurisdictions, and this actor only reads listing pages any visitor can see — no login, no private data. You are responsible for how you use the data — respect Djinni's Terms of Use and applicable law when handling any personal data, and consult a lawyer if you are unsure. See Apify's guide on the legality of web scraping.
Related actors
- Indeed Jobs Scraper — job listings from Indeed worldwide.
- Instahyre Jobs Scraper — India tech jobs with employer context.
- hh.ru Jobs Scraper — vacancies from Russia's largest job board.
- AllJobs.co.il Jobs Scraper — Israeli job listings with change monitoring.
- Freelancer.com Scraper — freelance projects and budgets.
Browse all ParseBird actors on Apify Store.