Guia de integração para ATSs v1.0

Publique as vagas dos seus clientes na Remotar

A integração é um feed XML: você publica um arquivo numa URL e a Remotar lê essa URL periodicamente. Não há API para chamar nem autenticação para implementar.

Baixar o XSD Baixar o exemplo

Endereço permanente do esquema: https://docs.remotar.com.br/feed/v1/remotar-feed-v1.xsd

Como funciona

  1. 1 · vocêPublica o feedUma URL HTTPS com todas as vagas abertas dos clientes que divulgam na Remotar.
  2. 2 · RemotarLê a URLA cada poucas horas, sem nenhuma ação sua.
  3. 3 · RemotarCura e publicaVaga nova entra na curadoria. Vaga que sumiu do feed é encerrada.
  4. 4 · candidatoCandidata-se no seu ATSO botão leva ao applyUrl da vaga. A candidatura acontece no seu sistema.

O feed é sempre uma fotografia completa, não uma lista de alterações. Não é preciso marcar vaga como nova, alterada ou removida: basta o feed refletir o estado atual.

Requisitos da URL

  • HTTPS, respondendo GET com status 200 e Content-Type: application/xml.
  • Codificação UTF-8.
  • URL estável. Se precisar de chave de acesso, coloque-a na própria URL (?token=…). Não suportamos cabeçalhos de autenticação.
  • Resposta completa em menos de 60 segundos. Recomendamos manter o arquivo abaixo de 20 MB.

Estrutura

feed mínimo
class="t"><?xml version="1.0" encoding="UTF-8"?>
class="t"><remotarFeed version="1.0">
  class="t"><generatedAt>2026-09-21T09:00:00-03:00class="t"></generatedAt>
  class="t"><jobs>
    class="t"><job>
      class="t"><id>vaga-10482class="t"></id>
      class="t"><title>Pessoa Desenvolvedora Back-end Python Sêniorclass="t"></title>
      class="t"><description><![CDATA[class="t"><p>Descrição em HTML…class="t"></p>]]>class="t"></description>
      class="t"><applyUrl>https://vagas.seu-ats.com.br/acme/vaga-10482class="t"></applyUrl>
      class="t"><workplace>remoteclass="t"></workplace>
      class="t"><company>
        class="t"><id>acmeclass="t"></id>
        class="t"><name>Acme Pagamentosclass="t"></name>
      class="t"></company>
    class="t"></job>
  class="t"></jobs>
class="t"></remotarFeed>
  • version é obrigatório e deve ser 1.0 nesta versão do formato.
  • generatedAt é o momento em que o arquivo foi gerado (ISO 8601 com fuso).
  • Dentro de <job> e de <company>, os elementos podem vir em qualquer ordem.
  • Use <![CDATA[ … ]]> em textos com HTML ou com os caracteres < e &.

Campos da vaga

Obrigatórios

CampoFormatoRegra
idLetras, números e . _ : -, até 100 caracteresIdentificador estável e único da vaga no seu ATS. Veja Identificadores.
titleTexto, até 255 caracteresTítulo da vaga, sem código interno nem nome da empresa.
descriptionHTML, até 50.000 caracteresDescrição completa: responsabilidades, requisitos e o que mais houver.
applyUrlURL https://Página de candidatura desta vaga no seu ATS.
workplaceremote · hybrid · onsiteModelo de trabalho. Veja Quais vagas entram.
companyBlocoEmpresa que contrata. Veja Campos da empresa.
location<city> e <state>Obrigatório em vaga híbrida. Cidade e UF de 2 letras (ex.: SP) do escritório.

Opcionais

Os opcionais melhoram a vaga na Remotar: aparecem como filtro, selo ou informação destacada. Mande sempre que tiver o dado.

CampoFormatoUso
publishedAtData e hora ISO 8601Data em que a vaga foi aberta.
contractTypeclt · pj · internship · temporary · freelancer · otherTipo de contratação.
seniorityinternship · junior · mid · senior · specialist · leadNível da vaga.
salarymin · max · currency · periodFaixa salarial. Veja Salário.
categoryTexto, até 255 caracteresÁrea da vaga no seu ATS (ex.: "Tecnologia").
pcdtrue · falsetrue quando a vaga é exclusiva ou afirmativa para pessoas com deficiência.
benefitsLista de <benefit>, até 50Benefícios oferecidos, um por item.

Campos da empresa

CampoObrigatórioRegra
idsimIdentificador estável do seu cliente. Todas as vagas da mesma empresa trazem o mesmo id.
namesimNome público da empresa, até 255 caracteres. Não use "Confidencial": vaga sem empresa identificada não é publicada.
websitenãoSite institucional. Ajuda a identificar a empresa na Remotar.
logoUrlnãoLogo em PNG, JPG ou SVG.
descriptionnãoApresentação curta da empresa, em texto ou HTML.

Quais vagas entram

A Remotar publica apenas vagas remotas e híbridas.

workplaceResultadoObservação
remoteentraSegue para a curadoria.
hybrid com locationentraSegue para a curadoria.
hybrid sem locationdescartadaSem cidade e UF, a pessoa não sabe onde fica o escritório.
onsiteignoradaPode vir no feed. Assim você não precisa filtrar.

Toda vaga passa pela curadoria da Remotar antes de aparecer no site. Na primeira vaga de uma empresa nova, também confirmamos a empresa. Por isso, a publicação não é imediata, e uma vaga pode não ser publicada se não seguir as políticas da Remotar.

Identificadores

O id da vaga e o id da empresa são o que liga o seu feed ao que está publicado na Remotar.

  • Nunca mude o id de uma vaga existente. Para nós, um id novo é uma vaga nova, e o antigo é uma vaga encerrada.
  • Nunca reaproveite um id para outra vaga, mesmo depois de a primeira ser encerrada.
  • Use o identificador interno do seu banco, não o título nem a URL.
  • O id da empresa é o mesmo em todas as vagas dela e em todas as leituras. Se o cliente mudar de nome, o id continua o mesmo.

Ciclo de vida da vaga

SituaçãoNo feedNa Remotar
Vaga abertaPresentePublica, depois da curadoria.
Vaga alteradaPresente, com os dados novosAtualiza.
Vaga fechada ou pausadaAusenteEncerra a vaga.
Vaga reabertaVolta, com o mesmo idReativa a vaga.
Nenhuma vaga aberta<jobs/> vazio, num feed válidoEncerra todas as vagas do feed.
Feed fora do ar ou inválidoErro HTTP, timeout ou XML inválidoNada muda. Mantém o último estado e tenta de novo na próxima leitura.

Um feed com erro nunca derruba as vagas publicadas. Só um feed válido e sem aquela vaga a encerra.

Descrição e salário

Descrição

  • Envie HTML simples: p, br, ul, ol, li, strong, em, h2h4 e a. Scripts, estilos, iframes, imagens e atributos de formatação são removidos.
  • Não inclua o link de candidatura na descrição: ele vem em applyUrl.
  • Descrições muito curtas prejudicam a curadoria e podem impedir a publicação.

Salário

bloco salary
class="t"><salary>
  class="t"><min>12000class="t"></min>
  class="t"><max>16000class="t"></max>
  class="t"><currency>BRLclass="t"></currency>
  class="t"><period>monthclass="t"></period>
class="t"></salary>
  • Valores inteiros, sem separador de milhar nem centavos.
  • max é obrigatório dentro de salary. Para salário fixo, mande só max.
  • currency: BRL, USD ou EUR. period: hour, month ou year.
  • Se a vaga não divulga salário, omita o bloco inteiro. Não mande 0.

Link de candidatura e rastreamento

Ao enviar a pessoa para o applyUrl, a Remotar acrescenta utm_source=remotar à URL, a menos que ela já traga um utm_source. Assim você mede as candidaturas vindas da Remotar. Garanta que o seu ATS aceite parâmetros extras na URL de candidatura.

Validando o feed

O XSD confere estrutura e formatos. Com xmllint:

shell
xmllint --noout --schema remotar-feed-v1.xsd seu-feed.xml

Ou em Python, com lxml:

python
from lxml import etree

schema = etree.XMLSchema(etree.parse("remotar-feed-v1.xsd"))
feed = etree.parse("seu-feed.xml")
schema.assertValid(feed)

O XSD não expressa duas regras, que conferimos na leitura: vaga hybrid precisa de location, e o id de cada empresa precisa ser estável entre leituras.

Elementos fora do esquema tornam o feed inválido. Se você precisa mandar um dado que o formato não prevê, fale com a gente: o formato cresce por versão.

Checklist antes de enviar a URL

  • O feed valida contra remotar-feed-v1.xsd.
  • A URL responde por HTTPS em menos de 60 segundos.
  • O feed contém todas as vagas abertas, não só as recentes.
  • Os ids de vaga e de empresa vêm do seu banco e não mudam.
  • Toda vaga híbrida tem cidade e UF.
  • O applyUrl abre a candidatura da vaga certa, sem exigir login prévio.
  • O applyUrl continua funcionando com ?utm_source=remotar no final.

Próximo passo

Com o feed validado, envie à Remotar a URL do feed, o nome do seu ATS com um contato técnico e, se houver, a lista dos clientes que já têm vagas no feed. Fazemos uma leitura de teste, mostramos o resultado (vagas aceitas, descartadas e o motivo de cada descarte) e só então ativamos a integração.

Versionamento

  • Mudanças compatíveis, como um campo opcional novo, sobem a versão menor: 1.1, 1.2. Um feed 1.0 continua válido.
  • Mudanças incompatíveis geram uma versão 2.0, com novo XSD e prazo de transição combinado com cada parceiro.

XSD e exemplo

Os dois arquivos oficiais da versão 1.0: remotar-feed-v1.xsd e exemplo-v1.xml. O exemplo traz uma vaga remota completa, uma híbrida e uma só com os campos obrigatórios, e valida contra o XSD.

Exemplo de feed exemplo-v1.xml
xml
class="t"><?xml version="1.0" encoding="UTF-8"?>
class="t"><remotarFeed version="1.0">
  class="t"><generatedAt>2026-09-21T09:00:00-03:00class="t"></generatedAt>
  class="t"><jobs>

    <!-- Vaga remota, com todos os campos opcionais preenchidos -->
    class="t"><job>
      class="t"><id>vaga-10482class="t"></id>
      class="t"><title>Pessoa Desenvolvedora Back-end Python Sêniorclass="t"></title>
      class="t"><description><![CDATA[
        class="t"><p>Buscamos uma pessoa desenvolvedora para evoluir nossa plataforma de pagamentos.class="t"></p>
        class="t"><h3>Responsabilidadesclass="t"></h3>
        class="t"><ul>
          class="t"><li>Projetar e manter APIs em Python (FastAPI)class="t"></li>
          class="t"><li>Participar das decisões de arquiteturaclass="t"></li>
        class="t"></ul>
        class="t"><h3>Requisitosclass="t"></h3>
        class="t"><ul>
          class="t"><li>Experiência sólida com Python e PostgreSQLclass="t"></li>
          class="t"><li>Vivência com filas e mensageriaclass="t"></li>
        class="t"></ul>
      ]]>class="t"></description>
      class="t"><applyUrl>https://vagas.exemplo-ats.com.br/acme/vaga-10482class="t"></applyUrl>
      class="t"><workplace>remoteclass="t"></workplace>
      class="t"><publishedAt>2026-09-18T14:30:00-03:00class="t"></publishedAt>
      class="t"><contractType>pjclass="t"></contractType>
      class="t"><seniority>seniorclass="t"></seniority>
      class="t"><salary>
        class="t"><min>12000class="t"></min>
        class="t"><max>16000class="t"></max>
        class="t"><currency>BRLclass="t"></currency>
        class="t"><period>monthclass="t"></period>
      class="t"></salary>
      class="t"><category>Tecnologiaclass="t"></category>
      class="t"><pcd>falseclass="t"></pcd>
      class="t"><benefits>
        class="t"><benefit>Auxílio home officeclass="t"></benefit>
        class="t"><benefit>Plano de saúdeclass="t"></benefit>
      class="t"></benefits>
      class="t"><company>
        class="t"><id>acmeclass="t"></id>
        class="t"><name>Acme Pagamentosclass="t"></name>
        class="t"><website>https://acme.com.brclass="t"></website>
        class="t"><logoUrl>https://acme.com.br/logo.pngclass="t"></logoUrl>
        class="t"><description>Fintech que simplifica pagamentos para pequenos negócios.class="t"></description>
      class="t"></company>
    class="t"></job>

    <!-- Vaga híbrida: location é obrigatório -->
    class="t"><job>
      class="t"><id>vaga-10517class="t"></id>
      class="t"><title>Analista de Dados Plenoclass="t"></title>
      class="t"><description><![CDATA[class="t"><p>Apoie o time comercial com análises e dashboards.class="t"></p>]]>class="t"></description>
      class="t"><applyUrl>https://vagas.exemplo-ats.com.br/beta/vaga-10517class="t"></applyUrl>
      class="t"><workplace>hybridclass="t"></workplace>
      class="t"><location>
        class="t"><city>Belo Horizonteclass="t"></city>
        class="t"><state>MGclass="t"></state>
      class="t"></location>
      class="t"><contractType>cltclass="t"></contractType>
      class="t"><company>
        class="t"><id>beta-logisticaclass="t"></id>
        class="t"><name>Beta Logísticaclass="t"></name>
      class="t"></company>
    class="t"></job>

    <!-- Vaga só com os campos obrigatórios -->
    class="t"><job>
      class="t"><id>vaga-10533class="t"></id>
      class="t"><title>Designer de Produtoclass="t"></title>
      class="t"><description><![CDATA[class="t"><p>Desenhe a experiência do nosso app.class="t"></p>]]>class="t"></description>
      class="t"><applyUrl>https://vagas.exemplo-ats.com.br/acme/vaga-10533class="t"></applyUrl>
      class="t"><workplace>remoteclass="t"></workplace>
      class="t"><company>
        class="t"><id>acmeclass="t"></id>
        class="t"><name>Acme Pagamentosclass="t"></name>
      class="t"></company>
    class="t"></job>

  class="t"></jobs>
class="t"></remotarFeed>
Esquema remotar-feed-v1.xsd
xsd
class="t"><?xml version="1.0" encoding="UTF-8"?>
<!--
  Feed de vagas Remotar — versão 1.0

  Esquema do XML que um ATS publica para enviar vagas à Remotar.
  Guia completo: README.md, na mesma pasta.

  Os filhos de <job> e de <company> podem vir em qualquer ordem.
  Elementos fora deste esquema tornam o feed inválido: se precisar de um
  campo novo, fale com a Remotar.
-->
class="t"><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">

  class="t"><xs:element name="remotarFeed">
    class="t"><xs:complexType>
      class="t"><xs:sequence>
        class="t"><xs:element name="generatedAt" type="xs:dateTime"/>
        class="t"><xs:element name="jobs">
          class="t"><xs:complexType>
            class="t"><xs:sequence>
              class="t"><xs:element name="job" type="Job" minOccurs="0" maxOccurs="unbounded"/>
            class="t"></xs:sequence>
          class="t"></xs:complexType>
          class="t"><xs:unique name="jobIdUnico">
            class="t"><xs:selector xpath="job"/>
            class="t"><xs:field xpath="id"/>
          class="t"></xs:unique>
        class="t"></xs:element>
      class="t"></xs:sequence>
      class="t"><xs:attribute name="version" use="required">
        class="t"><xs:simpleType>
          class="t"><xs:restriction base="xs:string">
            class="t"><xs:pattern value="1\.[0-9]+"/>
          class="t"></xs:restriction>
        class="t"></xs:simpleType>
      class="t"></xs:attribute>
    class="t"></xs:complexType>
  class="t"></xs:element>

  class="t"><xs:complexType name="Job">
    class="t"><xs:all>
      <!-- Obrigatórios -->
      class="t"><xs:element name="id" type="Identificador"/>
      class="t"><xs:element name="title" type="TextoCurto"/>
      class="t"><xs:element name="description" type="TextoLongo"/>
      class="t"><xs:element name="applyUrl" type="UrlHttps"/>
      class="t"><xs:element name="workplace" type="Workplace"/>
      class="t"><xs:element name="company" type="Company"/>

      <!-- Obrigatório quando workplace = hybrid ou onsite -->
      class="t"><xs:element name="location" type="Location" minOccurs="0"/>

      <!-- Opcionais -->
      class="t"><xs:element name="publishedAt" type="xs:dateTime" minOccurs="0"/>
      class="t"><xs:element name="contractType" type="ContractType" minOccurs="0"/>
      class="t"><xs:element name="seniority" type="Seniority" minOccurs="0"/>
      class="t"><xs:element name="salary" type="Salary" minOccurs="0"/>
      class="t"><xs:element name="category" type="TextoCurto" minOccurs="0"/>
      class="t"><xs:element name="pcd" type="xs:boolean" minOccurs="0"/>
      class="t"><xs:element name="benefits" type="Benefits" minOccurs="0"/>
    class="t"></xs:all>
  class="t"></xs:complexType>

  class="t"><xs:complexType name="Company">
    class="t"><xs:all>
      class="t"><xs:element name="id" type="Identificador"/>
      class="t"><xs:element name="name" type="TextoCurto"/>
      class="t"><xs:element name="website" type="UrlHttp" minOccurs="0"/>
      class="t"><xs:element name="logoUrl" type="UrlHttp" minOccurs="0"/>
      class="t"><xs:element name="description" type="TextoLongo" minOccurs="0"/>
    class="t"></xs:all>
  class="t"></xs:complexType>

  class="t"><xs:complexType name="Location">
    class="t"><xs:all>
      class="t"><xs:element name="city" type="TextoCurto"/>
      class="t"><xs:element name="state" type="UF"/>
    class="t"></xs:all>
  class="t"></xs:complexType>

  class="t"><xs:complexType name="Salary">
    class="t"><xs:all>
      class="t"><xs:element name="min" type="xs:nonNegativeInteger" minOccurs="0"/>
      class="t"><xs:element name="max" type="xs:positiveInteger"/>
      class="t"><xs:element name="currency" type="Currency"/>
      class="t"><xs:element name="period" type="SalaryPeriod"/>
    class="t"></xs:all>
  class="t"></xs:complexType>

  class="t"><xs:complexType name="Benefits">
    class="t"><xs:sequence>
      class="t"><xs:element name="benefit" type="TextoCurto" maxOccurs="50"/>
    class="t"></xs:sequence>
  class="t"></xs:complexType>

  <!-- Tipos simples -->

  class="t"><xs:simpleType name="Identificador">
    class="t"><xs:restriction base="xs:string">
      class="t"><xs:minLength value="1"/>
      class="t"><xs:maxLength value="100"/>
      class="t"><xs:pattern value="[A-Za-z0-9._:\-]+"/>
    class="t"></xs:restriction>
  class="t"></xs:simpleType>

  class="t"><xs:simpleType name="TextoCurto">
    class="t"><xs:restriction base="xs:string">
      class="t"><xs:minLength value="1"/>
      class="t"><xs:maxLength value="255"/>
      class="t"><xs:pattern value=".*\S.*"/>
    class="t"></xs:restriction>
  class="t"></xs:simpleType>

  class="t"><xs:simpleType name="TextoLongo">
    class="t"><xs:restriction base="xs:string">
      class="t"><xs:minLength value="1"/>
      class="t"><xs:maxLength value="50000"/>
    class="t"></xs:restriction>
  class="t"></xs:simpleType>

  class="t"><xs:simpleType name="UrlHttps">
    class="t"><xs:restriction base="xs:anyURI">
      class="t"><xs:pattern value="https://.+"/>
      class="t"><xs:maxLength value="2000"/>
    class="t"></xs:restriction>
  class="t"></xs:simpleType>

  class="t"><xs:simpleType name="UrlHttp">
    class="t"><xs:restriction base="xs:anyURI">
      class="t"><xs:pattern value="https?://.+"/>
      class="t"><xs:maxLength value="2000"/>
    class="t"></xs:restriction>
  class="t"></xs:simpleType>

  class="t"><xs:simpleType name="Workplace">
    class="t"><xs:restriction base="xs:string">
      class="t"><xs:enumeration value="remote"/>
      class="t"><xs:enumeration value="hybrid"/>
      class="t"><xs:enumeration value="onsite"/>
    class="t"></xs:restriction>
  class="t"></xs:simpleType>

  class="t"><xs:simpleType name="UF">
    class="t"><xs:restriction base="xs:string">
      class="t"><xs:enumeration value="AC"/>class="t"><xs:enumeration value="AL"/>class="t"><xs:enumeration value="AP"/>
      class="t"><xs:enumeration value="AM"/>class="t"><xs:enumeration value="BA"/>class="t"><xs:enumeration value="CE"/>
      class="t"><xs:enumeration value="DF"/>class="t"><xs:enumeration value="ES"/>class="t"><xs:enumeration value="GO"/>
      class="t"><xs:enumeration value="MA"/>class="t"><xs:enumeration value="MT"/>class="t"><xs:enumeration value="MS"/>
      class="t"><xs:enumeration value="MG"/>class="t"><xs:enumeration value="PA"/>class="t"><xs:enumeration value="PB"/>
      class="t"><xs:enumeration value="PR"/>class="t"><xs:enumeration value="PE"/>class="t"><xs:enumeration value="PI"/>
      class="t"><xs:enumeration value="RJ"/>class="t"><xs:enumeration value="RN"/>class="t"><xs:enumeration value="RS"/>
      class="t"><xs:enumeration value="RO"/>class="t"><xs:enumeration value="RR"/>class="t"><xs:enumeration value="SC"/>
      class="t"><xs:enumeration value="SP"/>class="t"><xs:enumeration value="SE"/>class="t"><xs:enumeration value="TO"/>
    class="t"></xs:restriction>
  class="t"></xs:simpleType>

  class="t"><xs:simpleType name="ContractType">
    class="t"><xs:restriction base="xs:string">
      class="t"><xs:enumeration value="clt"/>
      class="t"><xs:enumeration value="pj"/>
      class="t"><xs:enumeration value="internship"/>
      class="t"><xs:enumeration value="temporary"/>
      class="t"><xs:enumeration value="freelancer"/>
      class="t"><xs:enumeration value="other"/>
    class="t"></xs:restriction>
  class="t"></xs:simpleType>

  class="t"><xs:simpleType name="Seniority">
    class="t"><xs:restriction base="xs:string">
      class="t"><xs:enumeration value="internship"/>
      class="t"><xs:enumeration value="junior"/>
      class="t"><xs:enumeration value="mid"/>
      class="t"><xs:enumeration value="senior"/>
      class="t"><xs:enumeration value="specialist"/>
      class="t"><xs:enumeration value="lead"/>
    class="t"></xs:restriction>
  class="t"></xs:simpleType>

  class="t"><xs:simpleType name="Currency">
    class="t"><xs:restriction base="xs:string">
      class="t"><xs:enumeration value="BRL"/>
      class="t"><xs:enumeration value="USD"/>
      class="t"><xs:enumeration value="EUR"/>
    class="t"></xs:restriction>
  class="t"></xs:simpleType>

  class="t"><xs:simpleType name="SalaryPeriod">
    class="t"><xs:restriction base="xs:string">
      class="t"><xs:enumeration value="hour"/>
      class="t"><xs:enumeration value="month"/>
      class="t"><xs:enumeration value="year"/>
    class="t"></xs:restriction>
  class="t"></xs:simpleType>

class="t"></xs:schema>