---
title: "Cadastrar ou editar uma vaga externa"
method: PUT
path: "/api/v1/eu/externas/{id}"
tags: ["Seus dados"]
---

# Cadastrar ou editar uma vaga externa

`PUT /api/v1/eu/externas/{id}`

## Request

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

**Escreve na sua lista.** Com um `id` novo (um **uuid v4 aleatório** que você gera com `crypto.randomUUID()`, nunca derivado do link ou de outro dado: o id é global, e um previsível colidiria com o de outra conta e diria se ele já existe), cria a vaga externa e responde 201; com o `id` de uma que já é sua, edita e responde 200, e campo omitido fica como está. Repetir o mesmo `PUT` não cria outra: é assim que a criação é idempotente sem POST. Na criação, `empresa` e `cargo` são obrigatórios, **mas o `link` pode trazê-los**: link de vaga do Ashby, do Greenhouse ou do Lever é lido na API pública do ATS (timeout de poucos segundos) e preenche o que você não mandou; se não der, a resposta é 422 pedindo o campo. Link de uma vaga que **já está no catálogo** responde 409 `in_catalog` com o slug dela: acompanhe com `PUT /api/v1/eu/vagas/{slug}`. O mesmo link duas vezes na sua lista responde 409 `conflict`. `link` com `null` (ou texto vazio) apaga. Mudar só a etapa é mandar só `etapa`; ela só mexe em `atualizada_em` quando muda. `nota_no_historico` vai no histórico da vaga (na criação, no evento de entrada; sem `etapa`, como nota solta). `nota` é o nome antigo do mesmo campo, aceito por compatibilidade: **a primeira nota, que vai pro histórico** (desde 2026-10-12 a vaga externa não tem mais nota à parte), e na resposta `nota` é a nota mais antiga do histórico. `desfecho` só vale com a etapa `encerrada` (a mandada ou a atual; fora dela, 422), e sair de Encerrada limpa. Até 500 externas por conta, e até 200 em andamento (toda etapa menos `encerrada`): criar além de um dos dois responde 409 `conflict`; editar, inclusive reabrir uma encerrada, nunca é recusado pelo teto. Criar e editar têm limite próprio por conta, além do geral: 60 a cada 10 minutos e 200 por dia (passou, 429 `rate_limited` com `Retry-After`). Campo desconhecido no corpo responde 422.

## Path parameters

- `id` string, uuid, required

## Request body

- VagaExternaRequest
  - `empresa` string: Obrigatória na criação, a menos que o link a traga.
  - `cargo` string: Obrigatório na criação, a menos que o link o traga.
  - `link` string, nullable: Endereço completo, `http://` ou `https://`. Do Ashby, Greenhouse ou Lever, preenche cargo e empresa. `null` apaga.
  - `etapa` 'guardada' | 'aplicada' | 'processo' | 'oferta' | 'encerrada': A etapa, em slug ou no rótulo da tela. Na criação, o padrão é `guardada` (Salva).
  - `nota` string, nullable: A primeira nota, que vai pro histórico: na criação, a nota do evento de entrada; na edição, a nota desta escrita (o mesmo que `nota_no_historico`, que é o nome novo). Nota do histórico não se edita nem se apaga: `null` ou vazio não muda nada. As duas com textos diferentes responde 422.
  - `nota_no_historico` string, nullable: O que aconteceu, numa linha nova do histórico (junto da mudança de etapa, se houver).
  - `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`

Editada.

- VagaExternaResponse
  - `data` VagaExterna, required
    - `externa` true, required: Sempre `true`: a vaga não está no catálogo. Nas de `eu/vagas` sai `false`.
    - `id` string, uuid, required
    - `empresa` string, required
    - `cargo` string, required
    - `link` string, nullable, required: Como você colou; `null` sem link.
    - `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 do catálogo continua em `vaga.url`.
    - `nota` string, nullable, required: A primeira nota, que vai pro histórico: a mais antiga do `historico` desta vaga, ou `null`. Fica por compatibilidade; a linha do tempo inteira está em `historico`.
    - `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.
    - `salva_em` string, date-time, required
    - `atualizada_em` string, date-time, required: A última mudança de etapa, como nas vagas do catálogo.
    - `editada_em` string, date-time, required: A última edição de qualquer campo.
    - `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

- `201`: Criada.
- `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`: O `id` não tem a forma de uuid, ou é de uma vaga externa de outra conta. `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)
