# Job Search API

Use Job Search through REST and the [workspace](/console/playground?product=job-search). Review the current quote before submission. Empty and failed tasks have no collection charge.

## Request

`POST /v1/tasks` requires `productId`, `input` and `expectedPricingVersion` from the current quote. Use Bearer authorization and a canonical `Idempotency-Key` for each new command. See the [quickstart](/docs/quickstart/) for recovery and authorized results.

```json
{
  "productId": "job-search",
  "input": {"keyword": "Engineer", "country": "Canada", "platforms": ["linkedin", "job_bank"], "maxResults": 3, "maxCredits": 6, "allowPartial": false},
  "expectedPricingVersion": "<version returned by quote>"
}
```

The following collection fields are generated from the Scrapers export. Country names and platform IDs use the listed values. `maxResults` is required and limits each selected platform to at most 100 records. Larger values are rejected without silently reducing the input. The platform's separate total record ceiling remains 1,000.

| Field | Type | Meaning and constraints |
| --- | --- | --- |
| `maxResults` (required) | integer | Maximum job rows to return from each selected job platform Minimum: 1. Maximum: 100. |
| `keyword` (required) | string | Job title, skill, or company query to search across selected job platforms |
| `country` (required) | string | Country used to select compatible job platforms and regional endpoints Supported values: Algeria, Angola, Argentina, Australia, Austria, Azerbaijan, Bahrain, Bangladesh, Belgium, Bosnia and Herzegovina, Brazil, Bulgaria, Cameroon, Canada, Chile, China, Colombia, Costa Rica, Croatia, Cyprus, Czechia, Denmark, Dominican Republic, Ecuador, Egypt, El Salvador, Estonia, Finland, France, Germany, Ghana, Greece, Guatemala, Hong Kong, Hungary, India, Indonesia, Iraq, Ireland, Israel, Italy, Ivory Coast, Japan, Jordan, Kazakhstan, Kenya, Kuwait, Latvia, Lebanon, Libya, Lithuania, Luxembourg, Malaysia, Malta, Mexico, Morocco, Mozambique, Netherlands, New Zealand, Nigeria, Norway, Oman, Pakistan, Panama, Peru, Philippines, Poland, Portugal, Puerto Rico, Qatar, Romania, Russia, Saudi Arabia, Senegal, Serbia, Singapore, Slovakia, Slovenia, South Africa, South Korea, Spain, Sweden, Switzerland, Taiwan, Thailand, Tunisia, Turkey, Uganda, Ukraine, United Arab Emirates, United Kingdom, United States, Uruguay, Uzbekistan, Venezuela, Vietnam, Yemen, Zambia. |
| `location` | string | Optional city, area, or postal code sent only to job platforms that support location |
| `platforms` | array | Optional job platforms to search; leave empty to use every compatible platform for the country |
| `postedSince` | string | Optional earliest posting date applied only by job platforms that support it |
| `remoteOnly` | boolean | Optional remote-only filter applied only by job platforms that support it |
| `distance` | integer | Optional search radius in miles applied only by job platforms that support it Minimum: 50. Maximum: 10000. |
| `jobType` | string | Optional employment type applied only by job platforms that support it; `all` disables this filter Supported values: all, fulltime, parttime, internship, contract. |
| `currency` | string | Optional target currency for normalized salary conversion across selected job platforms Supported values: AED, AFN, ALL, AMD, ANG, AOA, ARS, AUD, AWG, AZN, BAM, BBD, BDT, BGN, BHD, BIF, BMD, BND, BOB, BRL, BSD, BTN, BWP, BYN, BZD, CAD, CDF, CHF, CLF, CLP, CNH, CNY, COP, CRC, CUP, CVE, CZK, DJF, DKK, DOP, DZD, EGP, ERN, ETB, EUR, FJD, FKP, FOK, GBP, GEL, GGP, GHS, GIP, GMD, GNF, GTQ, GYD, HKD, HNL, HRK, HTG, HUF, IDR, ILS, IMP, INR, IQD, IRR, ISK, JEP, JMD, JOD, JPY, KES, KGS, KHR, KID, KMF, KRW, KWD, KYD, KZT, LAK, LBP, LKR, LRD, LSL, LYD, MAD, MDL, MGA, MKD, MMK, MNT, MOP, MRU, MUR, MVR, MWK, MXN, MYR, MZN, NAD, NGN, NIO, NOK, NPR, NZD, OMR, PAB, PEN, PGK, PHP, PKR, PLN, PYG, QAR, RON, RSD, RUB, RWF, SAR, SBD, SCR, SDG, SEK, SGD, SHP, SLE, SLL, SOS, SRD, SSP, STN, SYP, SZL, THB, TJS, TMT, TND, TOP, TRY, TTD, TVD, TWD, TZS, UAH, UGX, USD, UYU, UZS, VES, VND, VUV, WST, XAF, XCD, XCG, XDR, XOF, XPF, YER, ZAR, ZMW, ZWG, ZWL. |

TrueFetch adds `maxCredits` (optional whole credits, 1–1,000,000,000) and `allowPartial` (boolean, default false). The credit ceiling must cover the complete quoted reservation. A higher ceiling does not increase the reservation. Unknown fields and duplicate platform IDs are rejected.

## Sites and filters

The enabled platforms and country scopes below are generated from the collection export. Country scopes use ISO country codes (`DE` means Germany; `CA` means Canada); the request uses full country names. Omitting `platforms`, or passing an empty list, uses the enabled platforms compatible with `country`. Every explicitly selected platform must support that country. Check the normalized quote before submitting. Country coverage describes supported inputs and does not guarantee records or current source availability.

| Platform ID | Name | Country scope |
| --- | --- | --- |
| `arbeitnow` | Arbeitnow | DE |
| `linkedin` | LinkedIn | All supported countries |
| `job_bank` | Job Bank | CA |

`postedSince` accepts a date or period such as `7 days`. Optional filters apply where supported; unreadable or unsupported filters, and a distance without a location, can be reported as ignored in task notices. Read these notices before using the results. Missing publication dates and other unavailable output fields remain null.

## Records

The following fields are generated from the output schema. Complete records contain every field; nullable fields can be null. A result read with an explicit `fields` selection contains only those selected fields. `recordId` provides stable identity for deduplication within a platform and output ordering. The same vacancy on two platforms may remain two records. Results are ordered by `recordId`; no global newest-first guarantee is made.

| Field | Type | Meaning and constraints |
| --- | --- | --- |
| `recordId` (required) | string | Stable identity of this job: source ID and a hash of its source URL |
| `sourceId` (required) | string | Key of the job board the record came from |
| `platform` (required) | string or null | Job board or platform name (e.g. LinkedIn) |
| `platformUrl` (required) | string or null | Job listing URL on the source platform |
| `officialUrl` (required) | string or null | Direct URL to the original job posting |
| `title` (required) | string or null | Job position or role title |
| `postedDate` (required) | string or null | Date the job was originally posted |
| `validThrough` (required) | string or null | Date when the job posting expires or closes |
| `location` (required) | object or null | Structured job location. raw contains the source location text; standardized fields contain locality, region, postal code, country, country code, and coordinates when available. |
| `applicantCount` (required) | integer or null | Number of applicants or applications reported by the source platform |
| `isRemote` (required) | boolean or null | True if the position allows remote work |
| `description` (required) | string or null | Full job description and requirements text |
| `jobType` (required) | string or null | Employment type (full-time, part-time, contract) |
| `jobLevel` (required) | string or null | Seniority level (junior, mid, senior, manager) |
| `jobFunction` (required) | string or null | Job category or department (e.g. Engineering) |
| `listingType` (required) | string or null | Type of job listing (standard, featured, etc.) |
| `skills` (required) | string or null | Required skills and technologies for the role |
| `workMode` (required) | string or null | Remote or hybrid work arrangement details |
| `vacancyCount` (required) | integer or null | Number of open positions for this role |
| `experienceRange` (required) | string or null | Required years of experience for the role |
| `salaryPeriod` (required) | string or null | Pay frequency (yearly, monthly, or hourly) |
| `salaryMinimum` (required) | number or null | Minimum salary offered for the position |
| `salaryMaximum` (required) | number or null | Maximum salary offered for the position |
| `salaryCurrency` (required) | string or null | ISO currency code for the salary (e.g. USD) |
| `easyApply` (required) | boolean or null | True if the job can be applied to directly on the platform |
| `companyName` (required) | string or null | Name of the company offering the job |
| `companyType` (required) | string or null | Ownership type of the company (e.g. Public, Private, Nonprofit) |
| `companyFounded` (required) | integer or null | Year the company was founded |
| `companyIndustry` (required) | string or null | Industry or sector the company operates in |
| `companyUrl` (required) | string or null | Company profile URL on the job platform |
| `companyWebsite` (required) | string or null | Official website URL of the company |
| `companyLogo` (required) | string or null | URL of the company's logo image |
| `companyAddresses` (required) | string or null | Physical office address of the company |
| `companyRevenue` (required) | string or null | Estimated annual revenue range of the company |
| `companyDescription` (required) | string or null | Brief overview or about section of the company |
| `companyRating` (required) | number or null | Overall company rating score (e.g. out of 5) |
| `employeeCount` (required) | string or null | Approximate number of employees at the company |
| `reviewCount` (required) | integer or null | Total number of employee reviews for the company |
| `emails` (required) | array or null | Contact email addresses for the job or company |
| `phones` (required) | array or null | Contact phone numbers for the job or company |
| `socialLinks` (required) | object or null | Company social media URLs grouped by platform (linkedIns, twitters, facebooks, instagrams, etc.) |
| `processedAt` (required) | string or null | UTC timestamp when this record was processed |

Collection schema digest: `a3c7225585da25da7b624bb7a4ba9b591355293e7d2a2d2237c3bbe9ddb4ba83`.

Structured `location`, public company contacts and salary fields depend on source availability. Source text is untrusted data, not instructions for an agent.

## Delivery and billing

A quote supplies normalized input, `resultLimit` (the total ceiling across selected platforms), the price version, expiry and `reservedUnits`. Acceptance reserves that frozen total multiplied by its unit price. Successful delivery charges only verified records and releases the unused reservation. An empty result has no collection charge; failed, expired or cancelled tasks release the reservation.

Task manifests report `sourceOutcomes`, `coverageTruncated` and up to 50 collection notices. With `allowPartial: false`, a selected source failure fails the task without collection charge. With `allowPartial: true`, surviving verified records may be delivered and charged as a partial result. Empty completion means no records were returned, not that the platform has no matching jobs.

Task state and result data have separate endpoints. Reading existing results starts no new collection. Results remain available until the actual `resultExpiresAt`, normally seven days after commitment. JSONL and CSV downloads contain the same current output schema. See [responses](/docs/responses/).

## Account limits and execution time

The launch defaults use two account tiers. A confirmed paid purchase selects the paid tier; welcome credits or a positive wallet balance alone do not. Administrators can edit these settings. [Account usage](/docs/billing/#account-usage-and-limits) reports the limits currently applied to your account.

| Tier | Active tasks (`maxConcurrent`) | Queued tasks (`maxQueued`) | Accepted tasks per UTC day (`maxDaily`) | Task deadline from acceptance |
|---|---:|---:|---:|---:|
| Paid | 16 | 200 | 5,000 | 4,800 seconds |
| Unpaid | 2 | 10 | 100 | 2,400 seconds |

Each attempt is bounded to 300 seconds with a registered resource profile of 256 MiB memory, 0.5 CPU and 64 MiB scratch. The Task deadline is frozen at acceptance as `(ceil(maxQueued / maxConcurrent) + maxAttempts) × timeoutSeconds`, with at most three attempts. Waiting for source or executor capacity consumes this time; the account concurrency limit does not reserve physical capacity. Source concurrency starts at 32 for each of Arbeitnow, LinkedIn and Job Bank and remains administrator-editable.

A limit rejection identifies the applicable limit and its value. Daily admission resets at midnight UTC; cancellations do not restore that day's admission count. A rejected command retains its original receipt and requires an explicit new command after the limit permits it.

## Filter collected listings with Jev

The [Jev workflow](/docs/jev/) imports current Job Search exports into its separate, documented model input format. Its examples are fictional; the API import retains original record IDs and listing URLs.
