---
title: "Acompanhar uma vaga, ou mudar a etapa"
method: PUT
path: "/api/v1/eu/vagas/{slug}"
tags: ["Seus dados"]
---

# Acompanhar uma vaga, ou mudar a etapa

`PUT /api/v1/eu/vagas/{slug}`

## Request

- Base URL: `https://rebasedev.com.br`
- URL: `https://rebasedev.com.br/api/v1/eu/vagas/{slug}`
- Auth: HTTP bearer

**Escreve na sua lista.** Põe a vaga em "Minhas vagas" com a etapa dada, ou muda a etapa de quem já está lá. Idempotente: repetir a mesma etapa não muda nada (nem a data de `atualizada_em`). `nota` vai no histórico da vaga junto da mudança (com a mesma etapa, vira uma nota solta; a mesma nota repetida em seguida não entra duas vezes). Só `nota`, sem `etapa`, acrescenta uma nota a uma vaga que já está na sua lista. `desfecho` diz como acabou e só vale com `encerrada` (fora dela, 422); `null` limpa, e sair de Encerrada limpa sozinho. Uma vaga guarda até 200 notas soltas (passou, 409); mudança de etapa nunca é recusada por isso. A etapa `encerrada` também oculta a vaga do seu catálogo, e voltar a etapa não desoculta (use `DELETE /api/v1/eu/ocultas/{slug}`). A vaga precisa estar no catálogo, ou já estar na sua lista: uma vaga que fechou depois de você salvar continua mudando de etapa. Campo desconhecido no corpo responde 422, em vez de ser ignorado.

## Path parameters

- `slug` string, required

## Request body

- AcompanharRequest: `etapa` é obrigatória, a menos que venha só a `nota` (nota solta).
  - `etapa` 'guardada' | 'aplicada' | 'processo' | 'oferta' | 'encerrada': A etapa, em slug. Aceita também o rótulo da tela, sem caixa nem acento ("Em processo", "salva").
  - `nota` string, nullable: O que aconteceu, pro histórico da vaga. Opcional.
  - `desfecho` 'aceitei_oferta' | 'recusei_oferta' | 'nao_passei' | 'sem_resposta' | 'desisti' | 'vaga_fechada' | 'null', nullable: Como o processo acabou, em slug: `aceitei_oferta` (Aceitei a oferta), `recusei_oferta` (Recusei a oferta), `nao_passei` (Não passei), `sem_resposta` (Sem resposta), `desisti` (Desisti), `vaga_fechada` (A vaga foi fechada). Só com a etapa `encerrada`; `null` nas outras e quando você não disse.

## Response `200`

Sucesso.

- AcompanhamentoResponse
  - `data` Acompanhamento, required
    - `externa` boolean, required
    - `slug` string, required
    - `etapa` 'guardada' | 'aplicada' | 'processo' | 'oferta' | 'encerrada', required: A etapa, em slug. É o contrato.
    - `etapa_rotulo` string, required: O rótulo da etapa como a tela mostra. Texto de exibição: pode mudar de redação.
    - `fechada` boolean, required: O anúncio saiu do ar. A vaga continua na lista: o processo não acabou por isso.
    - `oculta` boolean, required: Também está oculta no seu catálogo (a etapa `encerrada` oculta sozinha).
    - `salva_em` string, date-time, required
    - `atualizada_em` string, date-time, required: A última mudança de etapa. Repetir a mesma etapa não a mexe.
    - `vaga` Job, required
      - `slug` string, required
      - `title` string, required
      - `company` object, nullable, required
        - `name` string, required
        - `slug` string, required
      - `location` string, nullable, required
      - `hires_in_brazil` 'unknown' | 'yes' | 'no', required: O veredito do catálogo sobre a vaga contratar no Brasil. Vaga que a curadoria publicou à mão sai `yes`, e `decidido_pela_curadoria` diz que a decisão é nossa, não prova no texto. Na prática é sempre `yes`; as outras só aparecem em `eu/vagas`, na vaga que saiu do catálogo depois de acompanhada.
      - `decidido_pela_curadoria` boolean, required: `true` quando o `hires_in_brazil: yes` desta vaga é decisão da curadoria (a vaga foi publicada à mão, com motivo) e não prova achada no texto do anúncio. A prova e o motivo não saem na API. `false` na vaga que a regra do catálogo aprovou sozinha.
      - `remote` boolean, nullable, required: O campo cru do ATS, sem interpretação nossa. Nulo quando o ATS não declarou, que é o comum: **não quer dizer que a vaga não é remota**. A prova do catálogo está em `remoto_comprovado`.
      - `work_mode` 'remote' | 'hybrid' | 'onsite' | 'null', nullable, required: Como o ATS declarou o modelo de trabalho, normalizado. Campo cru do ATS: nulo quando ele não declarou, e isso não diz nada sobre a vaga ser remota. A prova do catálogo está em `remoto_comprovado`.
      - `remoto_comprovado` boolean, required: A vaga tem remoto comprovado: pela regra do catálogo (evidência no campo do ATS ou no texto do anúncio) ou pela curadoria, que a publicou à mão com motivo. Toda vaga que a API devolve passou por isso, então na prática é sempre `true`. É o fato do catálogo; `remote` e `work_mode` são o que o ATS declarou.
      - `seniority` 'júnior' | 'pleno' | 'sênior' | 'staff' | 'liderança' | 'null', nullable, required: O nível que o título anuncia; quando o título não diz, `pleno` se o anúncio pede de 2 a 4 anos de experiência. Nulo quando nem um nem outro diz: o catálogo não chuta.
      - `skills` string[], required
      - `skills_no_titulo` unknown[], required
        - unknown
      - `hiring_models` string[], required: O modelo de contrato no Brasil: `clt` (CLT, pago em reais), `pj` (PJ ou contractor), `eor` (employer of record). São os que o anúncio afirma ou, quando ele não diz, os da empresa. Vazia quando nem um nem outro diz (o `nao-informado` do filtro `modelo`). Lido do texto do anúncio com padrões fixos, sem IA.
      - `salary` string, nullable, required
      - `salary_min` integer, nullable, required
      - `salary_max` integer, nullable, required
      - `salary_currency` string, nullable, required
      - `salary_interval` 'YEAR' | 'MONTH' | 'HOUR' | 'null', nullable, required: A que período `salary_min` e `salary_max` se referem.
      - `published_at` string, date-time, nullable, required
      - `first_seen_at` string, date-time, nullable, required
      - `apply_url` string, required
      - `url` string, uri, required: A página da vaga no catálogo, em URL absoluta. É o link pra repassar a uma pessoa ou citar como fonte.
    - `url_da_ficha` string, uri, required: A página desta candidatura no site (Minhas vagas), com login: notas, histórico e CV. Pra mandar a pessoa ver o que foi anotado. O anúncio da vaga é o `link`, que fica ao lado.
    - `cv` object, nullable, required: O CV que você anexou a esta vaga no site, ou `null`. O texto dele sai em `GET .../cv`; o arquivo, só no site.
      - `nome` string, required: O nome do arquivo, limpo.
      - `tamanho` integer, required: Em bytes.
      - `enviado_em` string, date-time, required
    - `desfecho` 'aceitei_oferta' | 'recusei_oferta' | 'nao_passei' | 'sem_resposta' | 'desisti' | 'vaga_fechada' | 'null', nullable, required: Como o processo acabou, em slug: `aceitei_oferta` (Aceitei a oferta), `recusei_oferta` (Recusei a oferta), `nao_passei` (Não passei), `sem_resposta` (Sem resposta), `desisti` (Desisti), `vaga_fechada` (A vaga foi fechada). Só com a etapa `encerrada`; `null` nas outras e quando você não disse.
    - `desfecho_rotulo` string, nullable, required: O rótulo do desfecho como a tela mostra, ou `null`. Texto de exibição.
    - `historico` object[], required: Os últimos 20 eventos da vaga, do mais novo pro mais antigo: cada mudança de etapa e cada nota solta. Começa no dia em que a vaga entrou na lista (pra quem já tinha a vaga antes do histórico existir, 12/10/2026, no evento da etapa em que ela estava).
      - `em` string, date-time, required
      - `etapa_antes` 'guardada' | 'aplicada' | 'processo' | 'oferta' | 'encerrada' | 'null', nullable, required: A etapa de antes; `null` no evento em que a vaga entrou na lista e na nota solta.
      - `etapa` 'guardada' | 'aplicada' | 'processo' | 'oferta' | 'encerrada' | 'null', nullable, required: A etapa nova; `null` quando o evento é só uma nota.
      - `etapa_rotulo` string, nullable, required
      - `nota` string, nullable, required: O que aconteceu, escrito por você. Só a conta dona do token vê.

## Other responses

- `401`: Sem token, ou token inválido ou revogado. `code` é `unauthorized`, e a resposta traz `WWW-Authenticate: Bearer`. Gere um token em `/vagas/perfil/agentes` (entrando com o LinkedIn) e mande em `Authorization: Bearer <token>`.
- `403`: O token é válido, mas a conta não tem acesso ao catálogo pela API. `code` é `forbidden`. Gerar outro token não resolve: é a conta que precisa de acesso.
- `404`: A vaga não está no catálogo nem na sua lista (slug que não existe, ou vaga fechada que você não tinha salvo). Só com `nota`, a vaga tem que estar na sua lista. `code` é `not_found`.
- `409`: Conflito com o que já existe. `code` é `in_catalog` quando o link é de uma vaga do catálogo (a mensagem traz o slug pra acompanhar ela), ou `conflict` quando o link já está na sua lista ou a lista chegou ao teto.
- `422`: Parâmetro inválido, com `code` `invalid_params`: valor fora do teto (`por_pagina`, ou `pagina` acima de 500), número fracionário em `pagina` ou `por_pagina`, slug de skill, de nível ou de empresa inexistente, busca curta demais, `titulo` ou `esconder_ocultas` que não é booleano, `onde` fora de `titulo` e `tudo`; nas rotas de escrita, etapa desconhecida, skill fora do dicionário, campo desconhecido no corpo ou corpo que não é objeto JSON. Em qualquer rota, parâmetro com o caractere nulo (`\u0000`). No texto do CV (`.../cv`), `cv_ilegivel`: o PDF não tem texto que se leia.
- `429`: Mais de 60 chamadas no minuto, pela mesma conta (com token) ou pelo mesmo IP (sem). `code` é `rate_limited`. Espere o `Retry-After`; melhor ainda, leia o `X-RateLimit-Remaining` das respostas de sucesso e se autorregule antes de chegar aqui.

---

[API](https://skmtc.dev/rebasedev/apis/rebase-jobs-api.md) · [All operations](https://skmtc.dev/rebasedev/apis/rebase-jobs-api/llms.txt) · [OpenAPI document](https://skmtc.dev/rebasedev/apis/rebase-jobs-api/revisions/ec4ed03ac794?raw)
