Field reference
Every ApplySignals record describes one job posting from one employer career site. This page lists each field, where it comes from, and when it is empty. Empty means we could not read it from the posting; we do not guess.
Getting the data
Run the ApplySignals actor on Apify (launching soon; ask for early access). Each run writes one record per job to an Apify dataset, which you can download as JSON, CSV or Excel or read through the Apify API.
Paid runs receive the full description and the source quotes behind each requirement. Runs on Apify's free plan receive the first 300 or so characters of the description, no source quotes, and up to 100 jobs per day.
For volume or a direct API key, write to hello@applysignals.com.
A record at a glance
Shortened: the description and most requirements are cut for space.
{
"id": "as_e7oufdm25retpopycjktic5cqs",
"status": "live",
"title": "Senior Backend Engineer (Hybrid)",
"company": { "name": "Kestrel Freight GmbH", "board_url": "https://boards.greenhouse.io/kestrel" },
"url": "https://boards.greenhouse.io/kestrel/jobs/4021",
"apply_url": null,
"source": { "ats": "greenhouse", "board": "kestrel", "ats_job_id": "4021", "requisition_id": "R-118" },
"location": { "text": "Berlin, Germany", "city": "Berlin", "state": null, "country": "DE",
"postcode": null, "lat": null, "lon": null },
"work_arrangement": "hybrid",
"employment_type": "full_time",
"salary": { "min": 75000, "max": 90000, "currency": "EUR", "period": "year",
"text": "EUR 75,000 - 90,000 per year" },
"classification": { "seniority": "senior", "family": "engineering", "family_source": "llm_label",
"isco": { "code": "251", "label": "Software and applications developers and analysts" } },
"posted_at": "2026-10-20T00:00:00.000Z",
"first_seen_at": "2026-10-21T06:12:40.512Z",
"verified_at": "2026-10-24T05:03:11.090Z",
"updated_at": "2026-10-21T06:50:02.311Z",
"description": "You will build the services that route 40,000 shipments a day. ...",
"description_kind": "full",
"description_truncated": false,
"pii_redacted": true,
"requirements": {
"status": "ok",
"completeness": "complete",
"extractor": { "model": "openai/gpt-oss-20b", "schema_version": 2, "extracted_at": "2026-10-21T07:30:00.000Z" },
"items": [
{ "id": "r1", "importance": "required", "core": true, "operator": "any",
"evidence": ["5+ years of backend experience in Java or Kotlin"],
"children": [
{ "id": "r2", "importance": "required", "core": true, "kind": "skill", "name": "Java",
"evidence": ["Java or Kotlin"] },
{ "id": "r3", "importance": "required", "core": true, "kind": "skill", "name": "Kotlin",
"evidence": ["Java or Kotlin"] } ] }
],
"industries": [ { "name": "freight forwarding", "code": "5229", "label": "Other transportation support activities",
"evidence": ["route 40,000 shipments a day"] } ]
},
"tags": {
"skills_required": ["aws"], "skills_required_any": [["java", "kotlin"]],
"skills_preferred": [], "skills_preferred_any": [], "skills_core": ["java", "kotlin"],
"min_experience_months": { "overall": 60, "role": null, "skill": null, "industry": null, "unspecified": null },
"education": [], "certifications": [], "languages": ["de"],
"industries": [ { "code": "5229", "label": "Other transportation support activities", "name": "freight forwarding" } ]
}
}
Identity and source
| Field | Type | Meaning |
|---|---|---|
| id | string | Stable id: as_ plus 26 characters. It is derived from the ATS, the career site and the ATS's job id, so the same posting always has the same id. |
| status | string | live for every record a search returns. Looking up an id that left the dataset returns only { "id", "status": "removed" }; an id we never had returns not_found. |
| title | string | The job title as the employer wrote it. |
| company.name | string | The employer as named on its career site. |
| company.board_url | string or null | The career site the posting was read from. |
| url | string | The posting on the employer's career site. |
| apply_url | string or null | A separate application link when the ATS publishes one. |
| source.ats | string | The applicant tracking system, for example greenhouse, lever or workday. |
| source.board | string | The career site's identifier on that ATS. |
| source.ats_job_id | string | The ATS's own id for the posting. Unique only within one career site. |
| source.requisition_id | string or null | The employer's requisition number when published. |
Location and arrangement
| Field | Type | Meaning |
|---|---|---|
| location.text | string or null | The location exactly as the posting states it. |
| location.city | string or null | City, as parsed from the ATS's fields or the location text. |
| location.state | string or null | State, province or region. |
| location.country | string or null | ISO 3166-1 alpha-2 code in capitals, for example US or GB. |
| location.postcode | string or null | Postal code when published. |
| location.lat, location.lon | number or null | Coordinates, only when the ATS provides them. |
| work_arrangement | string or null | remote, hybrid or on_site, from the title, the location field and the source's own reading of the posting, which includes the description, so a phrase like "hybrid cloud" can occasionally give a wrong value. on_site appears only when the title, the location or the ATS says so. Null when unknown. |
Pay and employment
| Field | Type | Meaning |
|---|---|---|
| salary | object or null | Only what the employer publishes: min, max, currency (ISO 4217), period (year, month, week, day, hour) and the original text. We never estimate pay. |
| employment_type | string or null | full_time, part_time, contract, temporary or internship, from the ATS's employment type or commitment field. |
| commitment | string or null | The ATS's commitment text as written, for example "Full-time". |
| department, team | string or null | As listed by the employer. |
Classification
| Field | Type | Meaning |
|---|---|---|
| classification.seniority | string or null | Published only when the title states a level: intern, junior, senior, lead, manager, director, vp or c_level. "Backend Engineer" has no level and stays null; we do not assume mid-level. |
| classification.family | string or null | Job family, for example engineering, sales, healthcare or logistics. |
| classification.family_source | string or null | llm_label when the family comes from a language-model label of the title, rules when it comes from our title rules. |
| classification.isco | object or null | ISCO-08 minor group: a 3-digit code such as 251 and its label. Three digits separate, for example, software developers (251) from engineering professionals (214). |
Requirements
A language model reads the description (the first 18,000 characters; a longer one is marked partial) and lists what the posting asks for. Each item quotes the sentence it came from, and a document that fails our structural checks is never published. requirements.extractor names the model, the schema_version and the extracted_at time, so you can tell which records were read by which model.
| Field | Meaning |
|---|---|
| status | ok: requirements found. none_stated: the posting states none. partial: the extractor could not read the whole text. pending: not read yet. failed: the extraction did not pass validation. not_applicable: the description is too short to read. |
| completeness | complete or partial, as reported by the extractor. |
| items | The requirement tree. Top-level items are independent requirements. |
| items[].importance | required or preferred. |
| items[].core | True when the item is central to doing the job. |
| items[].operator, children | A group: all means every child applies; any means one of the alternatives is enough ("Java or Kotlin", or "a degree plus five years, or eight years"). |
| items[].kind, name | A single requirement: skill, experience, certification, education, language or industry, with its name. |
| items[].scope, minimum_months | For experience: the scope (overall, role, skill, industry) and the months the posting states. A duration is only given when the posting states a number. |
| items[].evidence | The exact quotes the item came from, with emails and phone numbers removed. Not included on Apify's free plan. |
| industries | The posting's business domain: a name, and an ISIC code and label when the name maps to one. |
Description text
| Field | Meaning |
|---|---|
| description | Plain text with line breaks. HTML and markdown are converted and entities decoded. Paid runs get the full text; free-plan runs get about 300 characters. Null when the career site publishes no description. |
| description_kind | full, snippet, or null when no description was requested or none exists. |
| description_truncated | True when the stored text reached our 25,000-character limit and the rest of the posting is missing. |
| pii_redacted | True when email addresses or phone numbers were replaced with [email removed] or [phone removed]. Salary ranges, years, dates and reference numbers are kept. |
Dates and freshness
| Field | Meaning |
|---|---|
| first_seen_at | When our scrapers first saw the posting on its career site. A posting that drops off for a few hours and comes back keeps its date, so it does not look new again. One that was gone long enough to be removed (about a day) gets a new date when it returns. |
| posted_at | The date the employer's ATS gives for the posting, when it gives one. Some ATSes re-date postings when they are refreshed. |
| verified_at | The last successful check of the career site that still listed the posting. |
| updated_at | The last time anything in this record changed: posting text, requirements or classification. |
All times are UTC in ISO 8601. A posting that disappears from its career site leaves the dataset once the next successful check confirms it is gone, or after 24 hours.
Filters
- Text: keywords across title, company and location, or in one of them
- Country (ISO codes), state and city
- ATS, work arrangement, employment type and seniority
- Job family and ISCO group, by 1 to 3 digits
- Skills: short skill names such as
pythonorsql, matched against required, preferred and alternative skills - Salary published, yes or no
- First seen after or before a date, and posted after or before a date
Results come newest first. Each request returns up to 500 records with a cursor for the next page.