# Techmap's Job Postings APIs - full documentation # Job Postings API (version 2.7.2) Search the last 3 months of job postings from 200+ sources in 250 countries & territories. Returns JSON (or CSV, RSS, Atom, XML, Parquet). Reference: https://api.techmap.io/jobs-api - OpenAPI: https://api.techmap.io/techmap-jobs_v2_openapi.json ## Quickstart (RapidAPI) 1. **Subscribe to the Basic plan** of the [Job Postings API on RapidAPI](https://rapidapi.com/techmap-io-techmap-io-default/api/daily-international-job-postings/pricing). It has no hard monthly limit - requests above the included quota are billed as overage (see [Errors & billing](https://api.techmap.io/errors-and-billing)). 2. **Copy your key** from the [RapidAPI listing](https://rapidapi.com/techmap-io-techmap-io-default/api/daily-international-job-postings) → *Endpoints* tab → code snippet → value of `X-RapidAPI-Key` - one key per RapidAPI application. 3. **Make your first call.** Replace `YOUR_API_KEY` with your key. A successful call returns HTTP **200**. ### curl ```bash curl --request GET \ --url 'https://daily-international-job-postings.p.rapidapi.com/api/v2/jobs/search?countryCode=us&title=developer' \ --header 'X-RapidAPI-Key: YOUR_API_KEY' \ --header 'X-RapidAPI-Host: daily-international-job-postings.p.rapidapi.com' ``` ### Python ```python import requests url = "https://daily-international-job-postings.p.rapidapi.com/api/v2/jobs/search" params = {"countryCode": "us", "title": "developer"} headers = { "X-RapidAPI-Key": "YOUR_API_KEY", "X-RapidAPI-Host": "daily-international-job-postings.p.rapidapi.com", } response = requests.get(url, params=params, headers=headers, timeout=30) response.raise_for_status() print(response.json()) ``` ### JavaScript ```javascript // Node.js 18+ or browser const url = new URL('https://daily-international-job-postings.p.rapidapi.com/api/v2/jobs/search'); url.search = new URLSearchParams({ 'countryCode': 'us', 'title': 'developer' }); const response = await fetch(url, { headers: { 'X-RapidAPI-Key': 'YOUR_API_KEY', 'X-RapidAPI-Host': 'daily-international-job-postings.p.rapidapi.com', }, }); if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`); console.log(await response.json()); ``` ### Java ```java // Java 11+ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; public class TechmapExample { public static void main(String[] args) throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://daily-international-job-postings.p.rapidapi.com/api/v2/jobs/search?countryCode=us&title=developer")) .header("X-RapidAPI-Key", "YOUR_API_KEY") .header("X-RapidAPI-Host", "daily-international-job-postings.p.rapidapi.com") .GET() .build(); HttpResponse response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() != 200) throw new RuntimeException(response.statusCode() + ": " + response.body()); System.out.println(response.body()); } } ``` Getting an error instead? See [Errors & billing](https://api.techmap.io/errors-and-billing). ## How to authenticate Requests are authenticated and billed by the marketplace you subscribe through. The base URL, the key and the plans depend on that marketplace. ### RapidAPI - **Base URL:** `https://daily-international-job-postings.p.rapidapi.com` - **Key:** header `X-RapidAPI-Key: YOUR_API_KEY` - **Host (optional):** header `X-RapidAPI-Host: daily-international-job-postings.p.rapidapi.com` - **Alternative:** query parameter `rapidapi-key=YOUR_API_KEY` in the URL instead of the header - **Where to find the key:** [RapidAPI listing](https://rapidapi.com/techmap-io-techmap-io-default/api/daily-international-job-postings) → *Endpoints* tab → code snippet → value of `X-RapidAPI-Key` - one key per RapidAPI application (see [RapidAPI docs](https://docs.rapidapi.com/docs/keys-and-key-rotation)). - **Plans and prices:** [RapidAPI pricing page](https://rapidapi.com/techmap-io-techmap-io-default/api/daily-international-job-postings/pricing) - Calling the backend directly (without RapidAPI) returns **401**. ## Endpoints ### GET /api/v2/jobs/search - Search job postings Use this endpoint to get the job postings themselves (10 per request). If you only need the number of matching postings, use count instead. This endpoint returns the paginated search results for a search query using various query parameters. The response is returned per default in JSON format and primarily consists of a JSON-LD payload containing up to 10 JobPostings per page (see https://schema.org/JobPosting). With the format parameter other output formats can be requested. This structured data can be directly integrated into a webpage to enhance visibility and indexing by search engines (e.g., https://developers.google.com/search/docs/appearance/structured-data/job-posting). Parameters: - `format` (query, string): The format of the output in json, csv, rss, atom, xml, or parquet (e.g., `format=rss`) Values: json, csv, rss, atom, xml, parquet. - `dateCreated` (query, string): The day the job posting was created / posted on using the format `YYYY-MM-DD` or `YYYY-MM`. If empty, the current day minus 2 days is used. - `dateCreatedMin` (query, string): The starting date for a date range search of when the job posting was created or posted, using the format `YYYY-MM-DD`. Only used if `dateCreated` is empty; `dateCreatedMin` and `dateCreatedMax` must be used together. - `dateCreatedMax` (query, string): The ending date for a date range search of when the job posting was created or posted, using the format `YYYY-MM-DD`. Only used if `dateCreated` is empty; `dateCreatedMin` and `dateCreatedMax` must be used together. - `page` (query, integer): The page of the paginated search results starting at 1. Pages contain 10 jobs and the defaults to 1 if not stated. - `cursor` (query, string): The cursor in a cursor-based pagination search started with 'true'. Does not work together with page-based pagination. Defaults to null if not stated. - `sort` (query, string): The sort order of the results by the time the job posting was collected: 'oldest' (default) or 'newest'. 'oldest' keeps page-based pagination stable while new jobs are added; 'newest' returns the most recent jobs first. Works with page-based and cursor-based pagination (a cursor keeps the sort order it was created with). Values: oldest, newest. - `isDirect` (query, string): A flag indicating if the job posting URL or externalApplyUrl links directly to the company's website. - `isDuplicate` (query, string): A flag indicating whether the job posting is considered a duplicate of another, either within the same source or across multiple sources. Note: We currently err on the safe side, resulting in more false duplicates than there are. - `isActive` (query, string): A flag indicating if the job posting has a dateActive not yet reached. - `isRecruiter` (query, string): A flag indicating if the job posting was posted by a recruiting firm. - `title` (query, string): Free-text search within the title of the job postings. - `skills` (query, string): The skills, keywords, or tags associated with the job posting. - `language` (query, string): The language the job posting is written in described by a 2-letter language code from ISO 639-1 such as 'en', 'de' or 'zh'. - `contractType` (query, string): The type of employment contract extracted from the job posting such as permanent, temporary, internship, etc. - `workType` (query, string): The type of work duration extracted from the job posting such as fulltime, parttime, flextime, etc. - `workPlace` (query, string): The workplace of the job, extracted from the job posting such as remote, hybrid, onsite, field, offshore, etc. - `hasSalary` (query, string): A flag indicating if the job posting contains salary information. - `minSalary` (query, number): The minimum salary of the job posting. Can be yearly, monthly, or hourly and any currency (exact data is stated in JsonLD result). - `industry` (query, string): The industry extracted from the job posting or categorization in the job board, such as advertising, agriculture, it, healthcare, etc. - `company` (query, string): The company that posted the job posting (can be a recruiting firm). - `department` (query, string): The department extracted from the job title such as, finance, it, hr, sales, etc. - `occupation` (query, string): The occupation type extracted from the job title reduced to a stem form incl. several synonyms. For example: programmer, executive, manager, engineer, nurse, etc. - `countryCode` (query, string): The country the job is located in described by a 2-letter country code from ISO 3166-1 alpha-2. Internally, we lower-case the countryCode and convert 'gb' into 'uk' and 'el' into 'gr' - you can use both spellings. - `state` (query, string): The state the workplace is located in, extracted from the job posting or geo-location. - `city` (query, string): The city the workplace is located in, extracted from the job posting or geo-location. - `postCode` (query, string): The postal / zip code the workplace is located in, extracted from the job posting or geo-location. - `timezone` (query, string): The timezone the job is located in such as CET, PST, or UTC - `timezoneOffset` (query, integer): The numeric offset of the timezone from UTC. - `timezoneMin` (query, integer): The minimum numeric offset of the timezone from UTC. Requires a 'timezoneMax' value greater than 'timezoneMin' to search in a timezone range. - `timezoneMax` (query, integer): The maximum numeric offset of the timezone from UTC. Must be larger than 'timezoneMin' to search in a timezone range. - `geoPointLat` (query, number): The geographic latitude of a GeoPoint used in a distance search. - `geoPointLng` (query, number): The geographic longitude of a GeoPoint used in a distance search. - `geoDistance` (query, string): The distance from a GeoPoint specified with 'geoPointLat' and 'geoPointLng'. - `geoTopLeftLat` (query, number): The geographic latitude of the top left GeoPoint in a bounding box search. - `geoTopLeftLng` (query, number): The geographic longitude of the top left GeoPoint in a bounding box search. - `geoBottomRightLat` (query, number): The geographic latitude of the bottom right GeoPoint in a bounding box search. - `geoBottomRightLng` (query, number): The geographic longitude of the bottom right GeoPoint in a bounding box search. - `portal` (query, string): The portal the job postings originated from. - `source` (query, string): The specific source with countrycode the job postings originated from such as careerjet, monster, linkedin, techmap, etc. Responses: 200, 400, 401, 403, 404, 405, 429, 500, 503, 509 ### GET /api/v2/jobs/count - Count job postings Use this endpoint when you only need numbers - e.g. for labour market analysis or to size a query before paging through search. It accepts the same filters as search. This endpoint returns the total number of job postings matching the specified query parameters. The response is per default a simple JSON object containing the count of job postings as well as the used query send to the underlying database. With the format parameter other output formats can be requested. Parameters: - `format` (query, string): The format of the output in json, csv, rss, atom, xml, or parquet (e.g., `format=rss`) Values: json, csv, rss, atom, xml, parquet. - `dateCreated` (query, string): The day the job posting was created / posted on using the format `YYYY-MM-DD` or `YYYY-MM`. If empty, the current day minus 2 days is used. - `dateCreatedMin` (query, string): The starting date for a date range search of when the job posting was created or posted, using the format `YYYY-MM-DD`. Only used if `dateCreated` is empty; `dateCreatedMin` and `dateCreatedMax` must be used together. - `dateCreatedMax` (query, string): The ending date for a date range search of when the job posting was created or posted, using the format `YYYY-MM-DD`. Only used if `dateCreated` is empty; `dateCreatedMin` and `dateCreatedMax` must be used together. - `isDirect` (query, string): A flag indicating if the job posting URL or externalApplyUrl links directly to the company's website. - `isDuplicate` (query, string): A flag indicating whether the job posting is considered a duplicate of another, either within the same source or across multiple sources. Note: We currently err on the safe side, resulting in more false duplicates than there are. - `isActive` (query, string): A flag indicating if the job posting has a dateActive not yet reached. - `isRecruiter` (query, string): A flag indicating if the job posting was posted by a recruiting firm. - `title` (query, string): Free-text search within the title of the job postings. - `skills` (query, string): The skills, keywords, or tags associated with the job posting. - `language` (query, string): The language the job posting is written in described by a 2-letter language code from ISO 639-1 such as 'en', 'de' or 'zh'. - `contractType` (query, string): The type of employment contract extracted from the job posting such as permanent, temporary, internship, etc. - `workType` (query, string): The type of work duration extracted from the job posting such as fulltime, parttime, flextime, etc. - `workPlace` (query, string): The workplace of the job, extracted from the job posting such as remote, hybrid, onsite, field, offshore, etc. - `hasSalary` (query, string): A flag indicating if the job posting contains salary information. - `minSalary` (query, number): The minimum salary of the job posting. Can be yearly, monthly, or hourly and any currency (exact data is stated in JsonLD result). - `industry` (query, string): The industry extracted from the job posting or categorization in the job board, such as advertising, agriculture, it, healthcare, etc. - `company` (query, string): The company that posted the job posting (can be a recruiting firm). - `department` (query, string): The department extracted from the job title such as, finance, it, hr, sales, etc. - `occupation` (query, string): The occupation type extracted from the job title reduced to a stem form incl. several synonyms. For example: programmer, executive, manager, engineer, nurse, etc. - `countryCode` (query, string): The country the job is located in described by a 2-letter country code from ISO 3166-1 alpha-2. Internally, we lower-case the countryCode and convert 'gb' into 'uk' and 'el' into 'gr' - you can use both spellings. - `state` (query, string): The state the workplace is located in, extracted from the job posting or geo-location. - `city` (query, string): The city the workplace is located in, extracted from the job posting or geo-location. - `postCode` (query, string): The postal / zip code the workplace is located in, extracted from the job posting or geo-location. - `timezone` (query, string): The timezone the job is located in such as CET, PST, or UTC - `timezoneOffset` (query, integer): The numeric offset of the timezone from UTC. - `timezoneMin` (query, integer): The minimum numeric offset of the timezone from UTC. Requires a 'timezoneMax' value greater than 'timezoneMin' to search in a timezone range. - `timezoneMax` (query, integer): The maximum numeric offset of the timezone from UTC. Must be larger than 'timezoneMin' to search in a timezone range. - `geoPointLat` (query, number): The geographic latitude of a GeoPoint used in a distance search. - `geoPointLng` (query, number): The geographic longitude of a GeoPoint used in a distance search. - `geoDistance` (query, string): The distance from a GeoPoint specified with 'geoPointLat' and 'geoPointLng'. - `geoTopLeftLat` (query, number): The geographic latitude of the top left GeoPoint in a bounding box search. - `geoTopLeftLng` (query, number): The geographic longitude of the top left GeoPoint in a bounding box search. - `geoBottomRightLat` (query, number): The geographic latitude of the bottom right GeoPoint in a bounding box search. - `geoBottomRightLng` (query, number): The geographic longitude of the bottom right GeoPoint in a bounding box search. - `portal` (query, string): The portal the job postings originated from. - `source` (query, string): The specific source with countrycode the job postings originated from such as careerjet, monster, linkedin, techmap, etc. Responses: 200, 400, 401, 403, 404, 405, 429, 500, 503 ### GET /api/v2/meta/jobs/distinct - List distinct values of a field Use this endpoint to find valid filter values (e.g. which industries or workplaces exist) - not to get job postings. This endpoint returns a list of distinct field values for the given query parameter. The response is per default a simple JSON object containing a list of keys usable as query parameter values and the count of jobs with this field value. With the format parameter other output formats can be requested. Notes This endpoint is not included in every plan (see Errors & billing). Without it, the response is 403 with requiredPlan and pricingUrl. The results are capped at 500 values and are calculated from job postings within the last month (i.e., current date minus 1 month). Usage Examples Used workPlace values: `/api/v2/meta/jobs/distinct?field=workPlace` Used industry values: `/api/v2/meta/jobs/distinct?field=industry` Parameters: - `field` (query, required, string): A field name used in a query as a parameter - `format` (query, string): The format of the output in json, csv, rss, atom, xml, or parquet (e.g., `format=rss`) Values: json, csv, rss, atom, xml, parquet. Responses: 200, 400, 401, 403, 404, 405, 429, 500, 503, 509 ### GET /api/v2/meta/jobs/statistics - Get value statistics of a field Use this endpoint to see how job postings are distributed over the values of a field (count and percentage per value). For a single number, use count. This endpoint returns a list of statistics of field values for the given query parameter. The response is per default a simple JSON object containing a list of keys usable as query parameter values, the count of jobs with this field value, and the percentage of jobs with this value. With the format parameter other output formats can be requested. Notes This endpoint is not included in every plan (see Errors & billing). Without it, the response is 403 with requiredPlan and pricingUrl. The results are capped at 100 values and are calculated from job postings within the last month (i.e., current date minus 1 month). Usage Examples Statistics on the workPlace field: `/api/v2/meta/jobs/statistics?field=workPlace` Statistics on the industry field: `/api/v2/meta/jobs/statistics?field=industry` Parameters: - `field` (query, required, string): A field name used in a query as a parameter - `format` (query, string): The format of the output in json, csv, rss, atom, xml, or parquet (e.g., `format=rss`) Values: json, csv, rss, atom, xml, parquet. Responses: 200, 400, 401, 403, 404, 405, 429, 500, 503, 509 ## Errors All errors return JSON with a `message` field. | Status | Cause | Solution | |---|---|---| | **400** Bad Request | A parameter value could not be parsed, e.g. an unknown `countryCode`, an invalid date or `sort` value. | Check the value against the parameter description. The `message` names the invalid parameter. | | **401** Unauthorized | The key is missing or invalid, or the request was sent directly to the backend instead of RapidAPI. | Send your key in the header `X-RapidAPI-Key` and use the base URL `https://daily-international-job-postings.p.rapidapi.com`. Copy the key again from the RapidAPI listing if it was rotated. | | **403** Forbidden | Either you are not subscribed to this API ("You are not subscribed to this API."), or the endpoint is not included in your plan (e.g. `/api/v2/meta/jobs/distinct` and `/api/v2/meta/jobs/statistics` need at least the Pro plan). | Subscribe to the Basic plan, or upgrade to the plan named in `requiredPlan`. The response contains `message`, `requiredPlan` and `pricingUrl`. | | **404** Not Found | The endpoint path does not exist (typo, wrong API version) or a required search parameter is missing, or the requested `field` does not exist. | Check the path and add at least one search parameter (e.g. `countryCode`). The `message` lists the allowed parameters or fields. | | **405** Method Not Allowed | Another HTTP method than GET was used. | Use GET. | | **429** Too Many Requests | Too many requests in a short time window (rate limit of your RapidAPI plan, e.g. 1 request/second on Basic). This is **not** a monthly limit - the plans have no hard limit, extra requests are billed as overage. RapidAPI also answers 429 after repeated calls with an invalid key. | Slow down and retry with exponential backoff (e.g. 1 s, 2 s, 4 s). If it persists, check that your key is valid. | | **500** Internal Server Error | An unexpected error on our side. | Retry once. If it persists, contact data@techmap.io with the full request URL (without your key). | | **502/504** Bad Gateway / Gateway Timeout | RapidAPI did not get a timely answer from the backend, typically for very broad queries. | Narrow the query (more filters, shorter date range) and retry. | | **503** Service Unavailable | The search backend is temporarily unavailable, or it could only answer partially (some index shards failed or timed out). Partial results are never returned as 200. | Retry later with exponential backoff. | | **509** Bandwidth Limit Exceeded | The response would be larger than 6 MB. | Request a more compact `format` or narrow the query. | ### Example: endpoint not included in your plan (403) ```json { "message": "Forbidden request to the API - this endpoint is not included in your plan. It is included from the Pro plan on.", "requiredPlan": "Pro", "pricingUrl": "https://rapidapi.com/techmap-io-techmap-io-default/api/daily-international-job-postings/pricing" } ``` ## Billing & overage ### RapidAPI - **Included:** every plan includes a number of requests per month (Basic, Pro, Ultra, Mega). - **Above the quota:** requests are **not blocked**. Each additional request is billed as **overage** at the per-request price of your plan. There is no hard limit, so you never get a "limit reached" error. - **When a bigger plan is cheaper:** as soon as your monthly overage costs more than the price difference to the next plan. Break-even = included requests + (price of next plan - price of your plan) / overage price per request. - **Current prices and quotas:** [RapidAPI pricing page](https://rapidapi.com/techmap-io-techmap-io-default/api/daily-international-job-postings/pricing) | Plan | Price / month | Included requests | Postings per request | Included postings | Each additional request | Rate limit | Next plan is cheaper above | |---|---|---|---|---|---|---|---| | Basic | $0 | 100 | 10 | 1,000 | $0.06 | 1 request/second | 5,834 postings / month | | Pro | $29 | 3,000 | 10 | 30,000 | $0.04 | 2 requests/second | 47,501 postings / month | | Ultra | $99 | 10,000 | 10 | 100,000 | $0.02 | 5 requests/second | 200,001 postings / month | | Mega | $299 | 30,000 | 10 | 300,000 | $0.01 | 10 requests/second | - | Example: with the Basic plan, 5,834 postings (584 requests) a month cost $0 + 484 × $0.06 = $29.04 - from then on the Pro plan ($29) is cheaper. Prices as listed on RapidAPI; the [pricing page](https://rapidapi.com/techmap-io-techmap-io-default/api/daily-international-job-postings/pricing) is authoritative. RapidAPI may add a bandwidth fee for very large transfers. The endpoints `/api/v2/meta/jobs/distinct` and `/api/v2/meta/jobs/statistics` are included from the **Pro** plan on. With a smaller plan they return **403** with `requiredPlan` and `pricingUrl`. # Job Postings RSS Feed API (version 1.6.2) Job postings as RSS/XML feeds, e.g. for job board backfill. The key goes into the feed URL, so the feed can be pasted into any job board importer. Reference: https://api.techmap.io/rss-api - OpenAPI: https://api.techmap.io/techmap-rss_v1_openapi.json ## Quickstart (RapidAPI) 1. **Subscribe to the Basic plan** of the [Job Postings RSS Feed API on RapidAPI](https://rapidapi.com/techmap-io-techmap-io-default/api/job-postings-rss-feed/pricing). It has no hard monthly limit - requests above the included quota are billed as overage (see [Errors & billing](https://api.techmap.io/errors-and-billing)). 2. **Copy your key** from the [RapidAPI listing](https://rapidapi.com/techmap-io-techmap-io-default/api/job-postings-rss-feed) → *Endpoints* tab → code snippet → value of `X-RapidAPI-Key` - one key per RapidAPI application. 3. **Make your first call.** Replace `YOUR_API_KEY` in the URL with your key. A successful call returns HTTP **200**. ### curl ```bash curl --request GET \ --url 'https://job-postings-rss-feed.p.rapidapi.com/api/rss/v1/jobs_full?countryCode=us&title=developer&rapidapi-key=YOUR_API_KEY' ``` ### Python ```python import requests url = "https://job-postings-rss-feed.p.rapidapi.com/api/rss/v1/jobs_full" params = {"countryCode": "us", "title": "developer", "rapidapi-key": "YOUR_API_KEY"} response = requests.get(url, params=params, timeout=30) response.raise_for_status() print(response.text) # RSS/XML feed ``` ### JavaScript ```javascript // Node.js 18+ or browser const url = new URL('https://job-postings-rss-feed.p.rapidapi.com/api/rss/v1/jobs_full'); url.search = new URLSearchParams({ 'countryCode': 'us', 'title': 'developer', 'rapidapi-key': 'YOUR_API_KEY' }); const response = await fetch(url); if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`); console.log(await response.text()); // RSS/XML feed ``` ### Java ```java // Java 11+ import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; public class TechmapExample { public static void main(String[] args) throws Exception { HttpRequest request = HttpRequest.newBuilder() .uri(URI.create("https://job-postings-rss-feed.p.rapidapi.com/api/rss/v1/jobs_full?countryCode=us&title=developer&rapidapi-key=YOUR_API_KEY")) .GET() .build(); HttpResponse response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() != 200) throw new RuntimeException(response.statusCode() + ": " + response.body()); System.out.println(response.body()); // RSS/XML feed } } ``` Getting an error instead? See [Errors & billing](https://api.techmap.io/errors-and-billing). ## How to authenticate Requests are authenticated and billed by the marketplace you subscribe through. The base URL, the key and the plans depend on that marketplace. ### RapidAPI - **Base URL:** `https://job-postings-rss-feed.p.rapidapi.com` - **Key:** query parameter `rapidapi-key=YOUR_API_KEY` in the request URL - no header needed. This lets you paste the feed URL into any job board importer that only accepts a URL. - **Where to find the key:** [RapidAPI listing](https://rapidapi.com/techmap-io-techmap-io-default/api/job-postings-rss-feed) → *Endpoints* tab → code snippet → value of `X-RapidAPI-Key` - one key per RapidAPI application (see [RapidAPI docs](https://docs.rapidapi.com/docs/keys-and-key-rotation)). - **Plans and prices:** [RapidAPI pricing page](https://rapidapi.com/techmap-io-techmap-io-default/api/job-postings-rss-feed/pricing) - Calling the backend directly (without RapidAPI) returns **401**. ## Endpoints ### GET /api/rss/v1/jobs_full - Get job postings as RSS feed Use this endpoint to import job postings into job board software or feed readers - the key goes into the URL, so the feed URL can be pasted anywhere. For JSON, use the Job Postings API. This endpoint returns an **RSS feed** containing job postings, including **full job descriptions**, based on the specified search query. Results can be paginated for efficient data retrieval. The RSS/XML data can be easily customized to meet specific needs and seamlessly integrated into a job board to backfill it with fresh, relevant job postings. Parameters: - `dateCreated` (query, string): The day the job posting was created / posted on using the format `YYYY-MM-DD` or `YYYY-MM`. If empty, the current day minus 2 days is used. - `dateCreatedMin` (query, string): The starting date for a date range search of when the job posting was created or posted, using the format `YYYY-MM-DD`. Only used if `dateCreated` is empty; `dateCreatedMin` and `dateCreatedMax` must be used together. - `dateCreatedMax` (query, string): The ending date for a date range search of when the job posting was created or posted, using the format `YYYY-MM-DD`. Only used if `dateCreated` is empty; `dateCreatedMin` and `dateCreatedMax` must be used together. - `countryCode` (query, string): The country the job is located in described by a 2-letter country code from ISO 3166-1 alpha-2. Internally, we lower-case the countryCode and convert 'gb' into 'uk' and 'el' into 'gr' - you can use both spellings. - `city` (query, string): The city the workplace is located in, extracted from the job posting or geo-location. - `title` (query, string): Free-text search within the title of the job postings. - `skills` (query, string): The skills, keywords, or tags associated with the job posting. - `language` (query, string): The language the job posting is written in described by a 2-letter language code from ISO 639-1 such as 'en', 'de' or 'zh'. - `workPlace` (query, string): The workplace of the job, extracted from the job posting such as remote, hybrid, onsite, field, offshore, etc. - `contractType` (query, string): The type of employment contract extracted from the job posting such as permanent, temporary, internship, etc. - `workType` (query, string): The type of work duration extracted from the job posting such as fulltime, parttime, flextime, etc. - `hasSalary` (query, string): A flag indicating if the job posting contains salary information. - `minSalary` (query, number): The minimum salary of the job posting. Can be yearly, monthly, or hourly and any currency. - `isDirect` (query, string): A flag indicating if the job posting URL links directly to the company's website or ATS career page. - `isDuplicate` (query, string): A flag indicating whether the job posting is considered a duplicate of another, either within the same source or across multiple sources. Note: We currently err on the safe side, resulting in more false duplicates than there are. - `isRecruiter` (query, string): A flag indicating if the job posting was posted by a recruiting firm. - `industry` (query, string): The industry extracted from the job posting or categorization in the job board, such as advertising, agriculture, it, healthcare, etc. - `company` (query, string): The company that posted the job posting (can be a recruiting firm). - `occupation` (query, string): The occupation type extracted from the job title reduced to a stem form incl. several synonyms. For example: programmer, executive, manager, engineer, nurse, etc. - `timezone` (query, string): The timezone the job is located in such as CET, PST, or UTC - `timezoneOffset` (query, integer): The numeric offset of the timezone from UTC. - `timezoneMin` (query, integer): The minimum numeric offset of the timezone from UTC. Requires a 'timezoneMax' value greater than 'timezoneMin' to search in a timezone range. - `timezoneMax` (query, integer): The maximum numeric offset of the timezone from UTC. Must be larger than 'timezoneMin' to search in a timezone range. - `geoPointLat` (query, number): The geographic latitude of a GeoPoint used in a distance search. - `geoPointLng` (query, number): The geographic longitude of a GeoPoint used in a distance search. - `geoDistance` (query, string): The distance from a GeoPoint specified with 'geoPointLat' and 'geoPointLng'. - `geoTopLeftLat` (query, number): The geographic latitude of the top left GeoPoint in a bounding box search. - `geoTopLeftLng` (query, number): The geographic longitude of the top left GeoPoint in a bounding box search. - `geoBottomRightLat` (query, number): The geographic latitude of the bottom right GeoPoint in a bounding box search. - `geoBottomRightLng` (query, number): The geographic longitude of the bottom right GeoPoint in a bounding box search. - `page` (query, integer): The page of the page-based pagination search results starting at 1. Defaults to 1 if not stated. Pagination is included from the Pro plan on - with smaller plans you always get page 1. - `pageSize` (query, integer): The number of job postings per request. Max and default depend on your plan: Basic 10, Pro 10, Ultra 100, Mega 1000. Responses: 200, 400, 401, 403, 404, 405, 429, 500, 503, 509 ## Errors All errors return JSON with a `message` field. | Status | Cause | Solution | |---|---|---| | **400** Bad Request | A parameter value could not be parsed, e.g. an unknown `countryCode` or an invalid date. | Check the value against the parameter description. The `message` names the invalid parameter. | | **401** Unauthorized | The key is missing or invalid, or the request was sent directly to the backend instead of RapidAPI. | Send your key in the query parameter `rapidapi-key` and use the base URL `https://job-postings-rss-feed.p.rapidapi.com`. Copy the key again from the RapidAPI listing if it was rotated. | | **403** Forbidden | You are not subscribed to this API ("You are not subscribed to this API."). | Subscribe to the Basic plan. | | **404** Not Found | The endpoint path does not exist (typo, wrong API version) or a required search parameter is missing. | Check the path and add at least one search parameter (e.g. `countryCode`). The `message` lists the allowed parameters. | | **405** Method Not Allowed | Another HTTP method than GET was used. | Use GET. | | **429** Too Many Requests | Too many requests in a short time window (rate limit of your RapidAPI plan, e.g. 1 request/second on Basic). This is **not** a monthly limit - the plans have no hard limit, extra requests are billed as overage. RapidAPI also answers 429 after repeated calls with an invalid key. | Slow down and retry with exponential backoff (e.g. 1 s, 2 s, 4 s). If it persists, check that your key is valid. | | **500** Internal Server Error | An unexpected error on our side. | Retry once. If it persists, contact data@techmap.io with the full request URL (without your key). | | **502/504** Bad Gateway / Gateway Timeout | RapidAPI did not get a timely answer from the backend, typically for very broad queries. | Narrow the query (more filters, shorter date range) and retry. | | **503** Service Unavailable | The search backend is temporarily unavailable, or it could only answer partially (some index shards failed or timed out). Partial results are never returned as 200. | Retry later with exponential backoff. | | **509** Bandwidth Limit Exceeded | The response would be larger than 6 MB. | Use a smaller `pageSize` or narrow the query. | ## Billing & overage ### RapidAPI - **Included:** every plan includes a number of requests per month (Basic, Pro, Ultra, Mega). - **Above the quota:** requests are **not blocked**. Each additional request is billed as **overage** at the per-request price of your plan. There is no hard limit, so you never get a "limit reached" error. - **When a bigger plan is cheaper:** as soon as your monthly overage costs more than the price difference to the next plan. Break-even = included requests + (price of next plan - price of your plan) / overage price per request. - **Current prices and quotas:** [RapidAPI pricing page](https://rapidapi.com/techmap-io-techmap-io-default/api/job-postings-rss-feed/pricing) | Plan | Price / month | Included requests | Postings per request | Included postings | Each additional request | Rate limit | Next plan is cheaper above | |---|---|---|---|---|---|---|---| | Basic | $0 | 100 | 10 | 1,000 | $0.06 | 1 request/second | 5,834 postings / month | | Pro | $29 | 3,000 | 10 | 30,000 | $0.04 | 1 request/second | 47,501 postings / month | | Ultra | $99 | 1,000 | 100 | 100,000 | $0.20 | 1 request/second | 200,001 postings / month | | Mega | $299 | 300 | 1,000 | 300,000 | $1 | 1 request/second | - | Example: with the Basic plan, 5,834 postings (584 requests) a month cost $0 + 484 × $0.06 = $29.04 - from then on the Pro plan ($29) is cheaper. Prices as listed on RapidAPI; the [pricing page](https://rapidapi.com/techmap-io-techmap-io-default/api/job-postings-rss-feed/pricing) is authoritative. RapidAPI may add a bandwidth fee for very large transfers. # Pagination, rate limits & quota ## Pagination ### Job Postings API: page-based Every search request returns up to **10 job postings**. Use `page` (starting at 1) and stop when `page × 10 ≥ totalCount` or the `result` array is empty. Page-based paging works for up to **10,000 results** (1,000 pages) of one query. ```bash curl 'https://daily-international-job-postings.p.rapidapi.com/api/v2/jobs/search?countryCode=de&dateCreated=2026-09&page=2' \ --header 'X-RapidAPI-Key: YOUR_API_KEY' ``` ### Job Postings API: cursor-based For more than 10,000 results - or for complete, stable paging while new postings arrive - send `cursor=true` with the first request. Each response contains `nextCursor`; pass it as `cursor` in the next request and stop when `nextCursor` is missing. The cursor keeps the `sort` order of the first request and cannot be combined with `page`. ```python import requests url = "https://daily-international-job-postings.p.rapidapi.com/api/v2/jobs/search" headers = {"X-RapidAPI-Key": "YOUR_API_KEY"} params = {"countryCode": "us", "dateCreated": "2026-09", "cursor": "true"} jobs = [] while True: data = requests.get(url, headers=headers, params=params, timeout=30).json() jobs.extend(data.get("result", [])) if not data.get("nextCursor"): break params["cursor"] = data["nextCursor"] print(len(jobs)) ``` Tip: `GET /api/v2/jobs/count` returns `totalCount` for the same filters - use it to size a query before paging through it. Each count is one request, too. ### RSS Feed API Postings per response depend on the plan (Basic 10, Pro 10, Ultra 100, Mega 1000); `pageSize` lowers it. Paging with `page` is included from the Pro plan on - smaller plans always get page 1. ## Rate limits RapidAPI limits the requests per second per plan. Above that you get **429 Too Many Requests** - wait and retry with exponential backoff (e.g. 1 s, 2 s, 4 s). | Plan | Job Postings API | RSS Feed API | |---|---|---| | Basic | 1 request/second | 1 request/second | | Pro | 2 requests/second | 1 request/second | | Ultra | 5 requests/second | 1 request/second | | Mega | 10 requests/second | 1 request/second | ## Quota and overage Every plan includes a number of requests per month. There is **no hard limit**: when the included requests are used up, further requests are billed as overage instead of being blocked. Prices and when a bigger plan pays off: [Errors & billing](https://api.techmap.io/errors-and-billing). RapidAPI adds these headers to every response, so you can track the quota in your code: | Header | Meaning | |---|---| | `x-ratelimit-requests-limit` | Requests included in your plan per month | | `x-ratelimit-requests-remaining` | Included requests left this month - at 0 further requests are billed as overage, not blocked | | `x-ratelimit-requests-reset` | Seconds until the included quota resets | | `x-rapidapi-request-id` | ID of the request - include it when you contact support | # Integrations ## Postman collections Import a collection into Postman (or Insomnia/Bruno), set the variable `rapidapiKey` to your key and send the first request. All parameters are included and described; optional ones are disabled. - [Job Postings API (Postman collection)](https://api.techmap.io/techmap-jobs_v2.postman_collection.json) - [OpenAPI spec](https://api.techmap.io/techmap-jobs_v2_openapi.json) - [Job Postings RSS Feed API (Postman collection)](https://api.techmap.io/techmap-rss_v1.postman_collection.json) - [OpenAPI spec](https://api.techmap.io/techmap-rss_v1_openapi.json) ## No-code and AI integrations All integrations are open source (MIT) and use your own key for the Job Postings API. ### MCP server for AI assistants Lets Claude, Cursor, VS Code and other MCP clients search and count job postings and build RSS feed URLs. [Docs](https://jobdatafeeds.com/integrations/mcp-server) · [npm @techmap/mcp-server](https://www.npmjs.com/package/@techmap/mcp-server) · [Smithery](https://smithery.ai/servers/techmap/job-postings) · [GitHub](https://github.com/TechMap/mcp.techmap.io) ### n8n community node Search jobs, build RSS feed URLs, trigger workflows on new jobs and use Techmap as a tool of the n8n AI Agent. [Docs](https://jobdatafeeds.com/integrations/n8n) · [npm n8n-nodes-techmap](https://www.npmjs.com/package/n8n-nodes-techmap) · [GitHub](https://github.com/TechMap/n8n.techmap.io) ### Zapier Trigger "New Job Posting" and search "Find Job Postings" (invite-only for now). [Docs](https://jobdatafeeds.com/integrations/zapier) · [GitHub](https://github.com/TechMap/zapier.techmap.io) ### Pipedream Action "Search Jobs" and polling source "New Jobs". [Docs](https://jobdatafeeds.com/integrations/pipedream) · [GitHub](https://github.com/TechMap/pipedream.techmap.io)