The jobs page is the core of any staffing website. This blueprint structures each open position with title, location, salary, and hiring details so AI systems can match candidates to your roles and surface your listings in job-related queries.
Job listings are the pages AI surfaces most often for staffing agencies. When someone asks an AI "find marketing jobs in Dallas" or "who is hiring for warehouse roles near me," these are the signals it looks for before recommending your listings:
JobPosting node. This is the Schema.org type that AI and Google for Jobs specifically look for when indexing employment opportunities.title, datePosted, and validThrough tell AI what the role is called, when it was listed, and whether it is still active. Expired jobs without validThrough waste AI's attention.hiringOrganization links each posting to the company offering the role. For staffing agencies, this can be your agency or the end client, depending on your model.jobLocation with a Place and PostalAddress tells AI exactly where the role is based, which is critical for location-filtered queries.baseSalary with value, currency, and unitText lets AI filter your roles by compensation level when candidates specify budget expectations.Without structured job data, AI may see your page but cannot parse individual listings from surrounding HTML. That means your jobs do not appear in Google for Jobs or AI-powered job searches.
Each field in the template below serves a specific role in how AI systems discover, classify, and recommend your business.
Researched and tested by Minnesota AI
nameurllogoCopy this prompt and paste it into Claude, ChatGPT, Cursor, or any AI coding tool. It will ask for your business details and generate ready-to-use JSON-LD schema for your page.
You are implementing AIFDS-compliant JSON-LD structured data for a Employment Agency Jobs page. AIFDS (AI-Friendly Data Structure) is a schema framework built on research into which structured data fields AI systems actually read, parse, and use when deciding whether to cite a page. Documentation at aifds.org. Before generating any code, ask me for the following information in a single numbered list. Do not generate schema until I have answered every required field. REQUIRED — do not proceed without these: 1. Agency name 2. City 3. Date posted 4. Domain 5. Employment type 6. Faq answer 7. Faq question 8. Jobs page description 9. Jobs page title 10. Job description 11. Job slug 12. Job title 13. Logo 14. Salary 15. Salary unit 16. State 17. Street address 18. Valid through 19. Zip OPTIONAL — ask for these but proceed if I skip them: 1. Any additional details not covered above Once I provide the information, output a complete JSON-LD script block ready to paste into the <head> of my HTML page. Output requirements: - Valid JSON-LD wrapped in <script type="application/ld+json"> tags - schema.org vocabulary only - Every AIFDS-required field for this industry and page type included - Include this data attribute on the script tag: data-aifds="aifds.org Employment Agency Jobs" - No placeholder text — omit missing optional fields rather than fill with examples - After the code block, list any optional fields skipped that would strengthen AI citation
Generated schema follows the AIFDS framework. Fields were selected based on research into AI crawler behavior. View the research at minnesota.ai
Copy the template below and replace every YOUR_* value with your own data. Add or remove JobPosting entries to match your active listings. This block goes in the <head> of your jobs page.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "JobPosting",
"@id": "https://YOUR_DOMAIN.com/jobs/YOUR_JOB_SLUG_1/#posting",
"title": "YOUR_JOB_TITLE_1",
"description": "YOUR_JOB_DESCRIPTION_1",
"datePosted": "YOUR_DATE_POSTED_1",
"validThrough": "YOUR_VALID_THROUGH_1",
"employmentType": "YOUR_EMPLOYMENT_TYPE_1",
"hiringOrganization": {
"@type": "EmploymentAgency",
"@id": "https://YOUR_DOMAIN.com/#organization",
"name": "YOUR_AGENCY_NAME",
"url": "https://YOUR_DOMAIN.com",
"logo": "https://YOUR_DOMAIN.com/YOUR_LOGO.png"
},
"jobLocation": {
"@type": "Place",
"address": {
"@type": "PostalAddress",
"streetAddress": "YOUR_STREET_ADDRESS_1",
"addressLocality": "YOUR_CITY_1",
"addressRegion": "YOUR_STATE_1",
"postalCode": "YOUR_ZIP_1",
"addressCountry": "US"
}
},
"baseSalary": {
"@type": "MonetaryAmount",
"currency": "USD",
"value": {
"@type": "QuantitativeValue",
"value": "YOUR_SALARY_1",
"unitText": "YOUR_SALARY_UNIT_1"
}
}
},
{
"@type": "JobPosting",
"@id": "https://YOUR_DOMAIN.com/jobs/YOUR_JOB_SLUG_2/#posting",
"title": "YOUR_JOB_TITLE_2",
"description": "YOUR_JOB_DESCRIPTION_2",
"datePosted": "YOUR_DATE_POSTED_2",
"validThrough": "YOUR_VALID_THROUGH_2",
"employmentType": "YOUR_EMPLOYMENT_TYPE_2",
"hiringOrganization": {
"@type": "EmploymentAgency",
"@id": "https://YOUR_DOMAIN.com/#organization",
"name": "YOUR_AGENCY_NAME",
"url": "https://YOUR_DOMAIN.com"
},
"jobLocation": {
"@type": "Place",
"address": {
"@type": "PostalAddress",
"streetAddress": "YOUR_STREET_ADDRESS_2",
"addressLocality": "YOUR_CITY_2",
"addressRegion": "YOUR_STATE_2",
"postalCode": "YOUR_ZIP_2",
"addressCountry": "US"
}
},
"baseSalary": {
"@type": "MonetaryAmount",
"currency": "USD",
"value": {
"@type": "QuantitativeValue",
"value": "YOUR_SALARY_2",
"unitText": "YOUR_SALARY_UNIT_2"
}
}
},
{
"@type": "JobPosting",
"@id": "https://YOUR_DOMAIN.com/jobs/YOUR_JOB_SLUG_3/#posting",
"title": "YOUR_JOB_TITLE_3",
"description": "YOUR_JOB_DESCRIPTION_3",
"datePosted": "YOUR_DATE_POSTED_3",
"validThrough": "YOUR_VALID_THROUGH_3",
"employmentType": "YOUR_EMPLOYMENT_TYPE_3",
"hiringOrganization": {
"@type": "EmploymentAgency",
"@id": "https://YOUR_DOMAIN.com/#organization",
"name": "YOUR_AGENCY_NAME",
"url": "https://YOUR_DOMAIN.com"
},
"jobLocation": {
"@type": "Place",
"address": {
"@type": "PostalAddress",
"streetAddress": "YOUR_STREET_ADDRESS_3",
"addressLocality": "YOUR_CITY_3",
"addressRegion": "YOUR_STATE_3",
"postalCode": "YOUR_ZIP_3",
"addressCountry": "US"
}
},
"baseSalary": {
"@type": "MonetaryAmount",
"currency": "USD",
"value": {
"@type": "QuantitativeValue",
"value": "YOUR_SALARY_3",
"unitText": "YOUR_SALARY_UNIT_3"
}
}
},
{
"@type": "EmploymentAgency",
"@id": "https://YOUR_DOMAIN.com/#organization",
"name": "YOUR_AGENCY_NAME",
"url": "https://YOUR_DOMAIN.com",
"logo": "https://YOUR_DOMAIN.com/YOUR_LOGO.png"
},
{
"@type": "WebPage",
"@id": "https://YOUR_DOMAIN.com/jobs/",
"name": "YOUR_JOBS_PAGE_TITLE",
"description": "YOUR_JOBS_PAGE_DESCRIPTION",
"isPartOf": {
"@id": "https://YOUR_DOMAIN.com/#website"
},
"breadcrumb": {
"@id": "https://YOUR_DOMAIN.com/jobs/#breadcrumb"
}
},
{
"@type": "BreadcrumbList",
"@id": "https://YOUR_DOMAIN.com/jobs/#breadcrumb",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://YOUR_DOMAIN.com/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Jobs",
"item": "https://YOUR_DOMAIN.com/jobs/"
}
]
},
{
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "YOUR_FAQ_QUESTION_1",
"acceptedAnswer": {
"@type": "Answer",
"text": "YOUR_FAQ_ANSWER_1"
}
},
{
"@type": "Question",
"name": "YOUR_FAQ_QUESTION_2",
"acceptedAnswer": {
"@type": "Answer",
"text": "YOUR_FAQ_ANSWER_2"
}
},
{
"@type": "Question",
"name": "YOUR_FAQ_QUESTION_3",
"acceptedAnswer": {
"@type": "Answer",
"text": "YOUR_FAQ_ANSWER_3"
}
}
]
}
]
}
It depends on your model. If you are posting on behalf of a client and the candidate will work at the client's company, use the client as hiringOrganization. If your agency is the employer of record, use your own agency. Google for Jobs expects the actual employer, so pick whichever entity the candidate will receive an offer from.
Include one JobPosting node for every active listing on the page. There is no upper limit, but each posting must be a genuinely distinct role. If you have paginated results, each page should only contain the postings visible on that page.
Without validThrough, AI and Google for Jobs cannot tell whether the listing is still active. Expired jobs without an expiration date continue to appear in results, which frustrates candidates and damages your agency's credibility. Always include this field and keep it updated.