Skip to main content

Coodesh Job Feed: XML job feed development guide

Specification of the XML feed through which a job board or ATS publishes jobs on the Coodesh job board: field schema, extensions, feed considerations and source approval.

The Coodesh Job Feed contains the information required to publish jobs from an external job board or applicant tracking system (ATS) on the Coodesh job board. The feed is a valid LinkedIn job XML feed plus one element: coodesh:category.

Requirements to take part

To publish jobs through the Coodesh Job Feed, the platform must:

  • Have a Coodesh workspace in the platform’s name. The source is registered in it, and someone on your team with a Coodesh user is set as responsible for the published jobs

  • Publish technology jobs. The Coodesh job board targets technology professionals. The categories the source may publish are agreed at registration, and a job outside them is refused

  • Send only jobs posted by the employers themselves on your platform, with no jobs aggregated from other sites

  • Have the employers’ authorization to publish on Coodesh the jobs and each company’s name, details, and logo. By sending the feed, the platform declares it has this authorization

  • Serve the feed at a stable, public https URL, with no authentication, responding within 60 seconds

  • Keep the file as a complete snapshot of the open jobs, as described in Feed considerations

Note. Coodesh may suspend a source that does not meet these requirements. Suspension closes no jobs: they simply stop being updated.

Creating the XML feed

The feed is an XML document served at a stable, public URL, with a <source> root element and one <job> element per open job.

The feed contains three kinds of element:

  • Mandatory — without them the job is refused

  • Recommended — LinkedIn standard elements that enrich the job

  • Coodesh extensions — elements in the coodesh namespace, optional except coodesh:category

Declare the namespace on the root element:

<source xmlns:coodesh="https://help.coodesh.com/articles/17067084">

Feed header

Children of <source>, outside each <job>. None is mandatory, but expectedJobCount is strongly recommended.

Field

Description

Type

coodesh:version

Version of the standard the file follows. Absent means 1.0

String

publisher

Name of your system

String

publisherUrl

Public address of your system

URL

lastBuildDate

When the file was generated

String

expectedJobCount

How many jobs the file should carry

Integer

Why the version lives in the file. A namespace is an identity, not a version. If it changed with every version, every feed already in production would declare one we no longer recognise. A file declaring a version newer than the supported one is still read, with a warning on the report.

Why expectedJobCount matters. Coodesh compares it with the number of <job> elements it managed to read. A mismatch means a truncated download, and the read is aborted without writing anything instead of closing the jobs the file lost.

Job posting field schema

The table lists the fields accepted inside each <job>.

Field

Description

Mandatory

Value type

partnerJobId

The job identifier in the partner system. Must stay stable for the life of the job

Yes

String, max 40 chars

company

Legal or trading name of the employer. Do not use the name of your own system

Yes

String

companyId

The company identifier on LinkedIn. The key by which Coodesh groups jobs of the same employer

Yes

Numeric

title

Job title, with no internal codes, addresses, dates or salary

Yes

String

description

Description of responsibilities. Accepts a limited set of HTML tags

Yes

String, min 100 chars

applyUrl

URL where the application is completed. Use the final URL, with no shortener or redirect

Yes

URL starting with https

city

City of the job

Yes, if location is absent

String

country

Country of the job

Yes, if location is absent

Two-letter ISO code

location

Location as a single string, in the City, Region format

Yes, if city and country are absent

String

state

State or region

No

String

postalCode

Postal code

No

String

workplaceTypes

Workplace nature. Values: On-site, Hybrid, Remote

No

String

jobtype

Employment status. Values: FULL_TIME, PART_TIME, CONTRACT, INTERNSHIP. VOLUNTEER refuses the job

No

String

experienceLevel

Seniority. Values: ENTRY_LEVEL, ASSOCIATE, MID_SENIOR_LEVEL, DIRECTOR, EXECUTIVE, INTERNSHIP, NOT_APPLICABLE

No

String

salaries

Salary range. Published only when period is MONTHLY

No

List of salary elements

skills

Up to ten relevant skills

No

List of skill elements

listDate

Original publication date

No

MM/DD/YYYY

expirationDate

Expected closing date

No

MM/DD/YYYY

posterEmail

Email of the job owner. Used only to verify the origin and never displayed

No

String

jobPostingAvailability

Visibility. Values: PUBLIC, INTERNAL. Defaults to PUBLIC

No

String

Note. If partnerJobId changes, Coodesh reads it as the previous job being closed and another one opened. Generate the identifier once and keep it.

Note. A salary range whose period is not MONTHLY is ignored, and the job is published without the range. The job board shows a monthly figure and does not store the period.

Note. A job with jobPostingAvailability set to INTERNAL is not published, and this raises no feed error. Internal jobs may stay in the same file.

What each value becomes on the published job

The three enumerations below come from the LinkedIn standard and are translated into what the candidate sees on the job board.

Workplace type, from workplaceTypes:

Value sent

Shown as

On-site

On-site, with the city

Hybrid

Hybrid, with the city

Remote

Remote

Without workplaceTypes, the job is treated as on-site when you send a city, and the city becomes the displayed location. If the job is remote, declare Remote explicitly.

Working hours, from jobtype:

Value sent

Effect

FULL_TIME

Full time

PART_TIME

Part time

CONTRACT

Full time, and suggests a contractor arrangement

INTERNSHIP

Full time, and suggests an internship

VOLUNTEER

Has no equivalent on the Coodesh job board and refuses the job

Seniority, from experienceLevel:

Value sent

Shown as

EXECUTIVE

Expert

DIRECTOR

Specialist

MID_SENIOR_LEVEL

Mid / Senior

ASSOCIATE

Mid

ENTRY_LEVEL

Junior

INTERNSHIP

Trainee

NOT_APPLICABLE

The job is published with no level

Need more precision? coodesh:level has seven steps and takes precedence over experienceLevel.

How to fill the salary range

The salaries block is nested. Send both ends, the currency on each, the period and the type.

<salaries>
<salary>
<lowEnd>
<amount><![CDATA[12000]]></amount>
<currencyCode><![CDATA[BRL]]></currencyCode>
</lowEnd>
<highEnd>
<amount><![CDATA[16000]]></amount>
<currencyCode><![CDATA[BRL]]></currencyCode>
</highEnd>
<period><![CDATA[MONTHLY]]></period>
<type><![CDATA[BASE_SALARY]]></type>
</salary>
</salaries>

Element

Rule

lowEnd/amount

Lower bound, digits only

highEnd/amount

Upper bound, digits only

currencyCode

Currency code, such as BRL, EUR or USD

period

Only MONTHLY is published. Any other period makes the range be ignored

type

BASE_SALARY

An incomplete range is ignored. If the lower bound, the upper bound or the currency is missing, the job is published with no salary range. It is never published half filled.

Confidential salary. To use the range for matching without showing it to the candidate, send <coodesh:salaryScope>private</coodesh:salaryScope>.

Coodesh extensions

Elements in the coodesh namespace, covering what the LinkedIn standard does not model. When present, they take precedence over the LinkedIn equivalent.

Field

Description

Mandatory

Value type

coodesh:category

Job category, by the code from the vocabulary published by Coodesh

Yes

String

coodesh:contractType

Contract type. Values: clt, pj, intern, freelance, flex, consulting, project, lecture, mvp, co_founder

No

String

coodesh:lookingFor

Field of work. Values: A vocabulary of its own, separate from the categories and written with underscores: backend, frontend, fullstack, devops, datascience, qa, design_ui, design_ux, mobile_android, cyber_security and others

No

String

coodesh:level

Level on the Coodesh scale. Values, most to least senior: expert, specialist, intermediary2, intermediary, beginner2, beginner, trainee

No

String

coodesh:salaryScope

Salary range visibility. Values: public, private

No

String

coodesh:companyLogo

URL of the employer logo, reachable over https without authentication

No

URL

coodesh:companyUrl

Employer website

No

URL

coodesh:languages

Required languages

No

List of coodesh:language

coodesh:requirements

Must-have requirements

No

List of coodesh:requirement

coodesh:differentials

Nice-to-have qualifications

No

List of coodesh:differential

coodesh:benefits

Benefits

No

List of coodesh:benefit

Note. A category code outside the published vocabulary refuses the job. Coodesh does not approximate to the closest category.

Note. coodesh:companyLogo and coodesh:companyUrl describe the employer, not the job. Repeat the same value on every job of the same companyId. The image is downloaded once and hosted by Coodesh from then on.

Description formatting

Send the description with the same HTML formatting used on your site, inside CDATA. Tags outside the list below are stripped, and their content is displayed as plain text.

Tag

Use

<p>

Paragraph

<br>

Line break

<ul>, <li>

List

<b>, <strong>

Bold

<i>, <em>

Italic

<u>

Underline

Note. Write real CDATA. Sending escaped markup makes the content arrive as literal text inside the description.

Why a job can be refused

A refusal applies to the job, never to the file: every other job is still published. The read report carries the count by reason.

Reason

What to fix

A mandatory field is missing

Fill the field. The report names which one

partnerJobId over 40 characters

Shorten the identifier

Description under 100 characters

Write a real description

applyUrl not starting with https

Send the final address over https

No location

Send city and country, or location

No coodesh:category

Declare the category

Category outside the vocabulary

Use a code from the category table

Category outside what was agreed for your source

Talk to Coodesh about widening the categories

jobPostingAvailability set to INTERNAL

Nothing. An internal job is not published by definition

jobtype set to VOLUNTEER

Nothing. That type does not exist on the Coodesh job board

partnerJobId repeated in the same file

Remove the duplicate. The first occurrence is kept

A company with that name already exists on Coodesh

Nothing on your side. The job is held for manual review

What the read tolerates and what it fills in

Situation

What Coodesh does

Element name in a different case, such as publisherurl

Recognises it all the same. The match ignores upper and lower case

Country spelled out, such as BRAZIL instead of BR

Converts it to the ISO code and records a warning on the read

Country it does not recognise

The job is published with no country

listDate missing

Uses the date of the first read as the publication date. Later reads do not rewrite it

workplaceTypes missing with a city filled in

Treats it as on-site, so as not to claim remote work you never declared

A skill that is not in the Coodesh taxonomy

Drops that skill only. The job is published as usual

More than ten skills

Takes the first ten

A new companyId

Creates the company profile on Coodesh from what the feed carries

The company name is a label, not a key. Coodesh groups an employer’s jobs by companyId. Changing the spelling of company does not create a new company; changing the companyId does.

Feed considerations

Coodesh reads the file at a regular interval and treats it as a full snapshot of the source’s active jobs. A job present in the file and absent from the database is created; present in both is updated; absent from the file is closed.

  • List every open job on every read. Never send a partial list, and never send only what changed since the last read

  • Include expectedJobCount. Coodesh compares it with the number of <job> elements read, to detect a truncated file

  • Keep the feed free of closed jobs and of duplicate jobs

  • Do not reuse the partnerJobId of a closed job on a new one

  • Do not close and reopen the same job repeatedly

  • Do not use a redirecting URL in applyUrl

  • Send only jobs posted directly by the employer on your platform. Do not include jobs aggregated from other sites

Note. Because a job’s absence from the file is what closes it, a partial file would close jobs that are still open. If the feed answers an error, arrives malformed, or has no jobs, the read is aborted without writing anything. If it shrinks sharply, the source is suspended.

What happens when you change a job

On every read, a job still present in the file is updated from what the file carries. Title, description, location, salary, skills and every other field come to reflect the file.

Two exceptions, so history is not rewritten:

Field

Behaviour on update

Publication date

Keeps the date of the first read, unless you send listDate

The job address on Coodesh

Does not change, even if the title changes

To close a job, simply remove it from the file. Sending an expirationDate in the past also closes it, even if it stays listed.

How to request registration

To register a feed, write to help@coodesh.com with the subject Coodesh Job Feed and this information:

  • Platform name and, if it already exists, its Coodesh workspace

  • Feed URL

  • Categories the source will publish, using the codes in the Category vocabulary

  • Name and email of the technical contact, who receives the sample read report

  • Email of the person set as responsible for the published jobs

With this information, Coodesh registers the source and runs the sample read described in Source approval.

Source approval

Every source goes through a one-time approval before it publishes.

  1. Registration. The partner sends the request described in How to request registration. Coodesh registers the source as pending

  2. Sample read. The first read does not publish. It runs the whole process and returns a report with what would be published, what would be refused, and the reason for each refusal

  3. Approval. The source is approved from the report. If there is a problem, the partner fixes the feed and a new sample is produced

  4. Automatic publishing. Subsequent reads publish with no intervention

After approval, two checks stay active:

  • Category filter. A job whose category falls outside what was agreed is refused, with the reason recorded in the report

  • Protection against an incomplete read. An HTTP error, malformed XML, an expectedJobCount mismatch, or a file with no jobs aborts the read without writing anything and alerts the Coodesh team. A sharp drop in job count suspends the source and also alerts the team

Note. A suspended source closes no jobs. It simply stops receiving updates until the problem is resolved.

When to notify Coodesh

Write to help@coodesh.com, with the subject Coodesh Job Feed, before you:

  • Change the feed URL. The source keeps reading the registered URL until it is updated

  • Publish categories beyond the agreed ones. Jobs in a new category are refused until the source’s list is updated

  • Pause or end the integration. A file with no jobs does not close the published jobs: the read is aborted as a safeguard. To remove the jobs from Coodesh, ask for the source to be closed

If the source is suspended, fix the feed and ask for reactivation at the same address. A suspended source is read again only once Coodesh reactivates it.

How the job appears on Coodesh

A job that sends only the mandatory layer is published like this: category, location and the button that takes the candidate to your application address.

A job carrying the mandatory layer only: category and location

Each recommended field adds one more attribute to the same job. Here it gained working hours, seniority, contract type, salary range and workplace type.

The same job with the recommended fields filled in: six attributes instead of two

Example feed

The first job carries the mandatory fields only. The second adds the recommended fields and some extensions.

<?xml version="1.0" encoding="UTF-8"?>
<source xmlns:coodesh="https://help.coodesh.com/articles/17067084">
<publisher><![CDATA[Nome do parceiro]]></publisher>
<publisherUrl><![CDATA[https://parceiro.com]]></publisherUrl>
<lastBuildDate><![CDATA[2026-09-22T15:10:36.186Z]]></lastBuildDate>
<expectedJobCount><![CDATA[2]]></expectedJobCount>
<job>
<partnerJobId><![CDATA[a7f3c2e1-9b44-4d10-8e55-1c0d7f2a9b31]]></partnerJobId>
<company><![CDATA[BLIV Gestão e Negócios]]></company>
<companyId><![CDATA[101543998]]></companyId>
<title><![CDATA[Pessoa Desenvolvedora Back-end Pleno]]></title>
<description><![CDATA[<p>Job description with at least 100 characters.</p>]]></description>
<applyUrl><![CDATA[https://bliv.parceiro.com/vagas/BLI000165]]></applyUrl>
<city><![CDATA[João Pessoa]]></city>
<state><![CDATA[PB]]></state>
<country><![CDATA[BR]]></country>
<coodesh:category><![CDATA[backend]]></coodesh:category>
</job>
<job>
<partnerJobId><![CDATA[b81d4f0e-2c37-4a59-9f61-3e7a8c5d0b44]]></partnerJobId>
<company><![CDATA[TSEA Energia]]></company>
<companyId><![CDATA[2535577]]></companyId>
<title><![CDATA[Pessoa Engenheira de Dados Sênior]]></title>
<description><![CDATA[<p>Job description with at least 100 characters.</p>]]></description>
<applyUrl><![CDATA[https://tsea.parceiro.com/vagas/TSE000431]]></applyUrl>
<city><![CDATA[São Paulo]]></city>
<state><![CDATA[SP]]></state>
<country><![CDATA[BR]]></country>
<postalCode><![CDATA[04538-133]]></postalCode>
<workplaceTypes><![CDATA[Hybrid]]></workplaceTypes>
<jobtype><![CDATA[FULL_TIME]]></jobtype>
<experienceLevel><![CDATA[MID_SENIOR_LEVEL]]></experienceLevel>
<salaries>
<salary>
<lowEnd><amount><![CDATA[12000]]></amount><currencyCode><![CDATA[BRL]]></currencyCode></lowEnd>
<highEnd><amount><![CDATA[16000]]></amount><currencyCode><![CDATA[BRL]]></currencyCode></highEnd>
<period><![CDATA[MONTHLY]]></period>
<type><![CDATA[BASE_SALARY]]></type>
</salary>
</salaries>
<expirationDate><![CDATA[11/15/2026]]></expirationDate>
<posterEmail><![CDATA[recrutamento@tsea.com.br]]></posterEmail>
<jobPostingAvailability><![CDATA[PUBLIC]]></jobPostingAvailability>
<coodesh:category><![CDATA[data-science]]></coodesh:category>
<coodesh:contractType><![CDATA[clt]]></coodesh:contractType>
<coodesh:companyLogo><![CDATA[https://cdn.parceiro.com/tsea/logo.png]]></coodesh:companyLogo>
</job>
</source>

Category vocabulary

Accepted values for coodesh:category. Send the code, never the name. A code outside this list refuses the job.

Code

Category

backend

Back-End

db

Banco de Dados

customer-success

Customer Success

cyber-security

Cyber Segurança

datascience

Data Science

design-ui

Design/UI

design-ux

Design/UX

devops

DevOps

financial

Financeiro

frontend

Front-End

fullstack

Full-Stack

management

Gestão

ia

Inteligência Artificial

marketing

Marketing

mobile

Mobile

human-resources

Recursos Humanos

tech-support

Suporte Técnico

qa

Testes/Q.A

sales

Vendas

References

Did this answer your question?