Pular para o conteúdo

API v1 · Guia

Paginação e updatedSince

Percorra listas com cursor e sincronize só o que mudou com updatedSince, passo a passo.

Listas respondem { "data": [...], "nextCursor": "...", "hasMore": true }. Para a página seguinte, repita o mesmo pedido com cursor=<nextCursor>. Quando hasMore for false, nextCursor vem null e a lista acabou. A ordem é estável: um registro nunca aparece duas vezes nem fica de fora entre páginas, mesmo com datas de criação iguais.

Para sincronizar só o que mudou, guarde a hora em que a sincronização começou e, na próxima, envie updatedSince com essa hora.

Percorrer uma lista inteira

Peça páginas de 100 itens (o máximo) e siga o nextCursor até hasMore vir false. Envie o cursor exatamente como veio.

Node.js
const BASE = "https://rumocrm.com/api/v1";
const CABECALHOS = { Authorization: `Bearer ${process.env.RUMO_TOKEN}` };

// Devolve todos os itens de uma lista, página por página.
async function* todos(caminho, filtros = {}) {
  let cursor = null;
  do {
    const url = new URL(BASE + caminho);
    for (const [chave, valor] of Object.entries({ ...filtros, limit: 100 })) url.searchParams.set(chave, valor);
    if (cursor) url.searchParams.set("cursor", cursor);

    const resposta = await fetch(url, { headers: CABECALHOS });
    if (!resposta.ok) throw new Error(`${resposta.status}: ${await resposta.text()}`);
    const pagina = await resposta.json();

    yield* pagina.data;
    cursor = pagina.hasMore ? pagina.nextCursor : null;
  } while (cursor);
}

Sincronização incremental, passo a passo

  1. Primeira carga. Anote a hora de início, percorra a lista inteira sem updatedSince e grave cada registro no seu sistema pelo id (cria se não existe, atualiza se existe).
  2. Guarde a marca. Terminou sem erro? Salve a hora de início como a marca da última sincronização. Se falhar no meio, não salve: a próxima rodada repete do mesmo ponto e nada se perde.
  3. Próximas rodadas. Anote a nova hora de início e peça só o que mudou desde a marca, com uma folga de um minuto para trás: updatedSince=<marca − 1 min>. Percorra todas as páginas gravando pelo id.
  4. Avance a marca. Ao terminar, salve a nova hora de início.

Por que funciona: updatedSince é inclusivo (igual ou depois) e a folga cobre a diferença entre o relógio do seu servidor e o nosso. Um registro alterado durante a rodada volta na rodada seguinte e um criado durante a rodada também; como você grava pelo id, repetir não duplica nada.

Não troque os filtros entre uma página e outra: o cursor vale para a lista que o gerou e, alterado, responde 400 invalid_cursor. Para reagir na hora em vez de perguntar de tempos em tempos, use os webhooks.

Node.js
const FOLGA_MS = 60_000;

async function sincronizarContatos() {
  const marca = await lerMarca(); // null na primeira carga
  const inicio = new Date();

  const filtros = marca ? { updatedSince: new Date(marca.getTime() - FOLGA_MS).toISOString() } : {};
  for await (const contato of todos("/contacts", filtros)) {
    await gravarPeloId(contato); // upsert no seu banco
  }

  await salvarMarca(inicio); // só depois de terminar sem erro
}

Listas que aceitam updatedSince

  • GETListar contatos /contacts
  • GETListar empresas /companies
  • GETListar negócios /deals
  • GETListar canais /channels
  • GETListar conversas /conversations
  • GETListar mensagens da conversa /conversations/{id}/messages
PróximoErros