Open Finance (TecnoSpeed)

Integração da WebApiAlcance com a TecnoSpeed para capturar o extrato bancário dos clientes via Open Finance. O domínio cobre o pagador (o cliente PJ cadastrado na TecnoSpeed), as contas bancárias do cliente, o consentimento (link que o cliente abre para autorizar o banco), os agendamentos extras de coleta e o financeiro (resumo, transações, CSV, protocolos de coleta, atualização de saldos e reprocessamento manual de um período).

São quatro routers montados no mesmo prefixo /tecnospeed: agendamentos, pagador, contas e financeiro. As transações capturadas aqui são as mesmas que o siscontabil importa como lançamentos contábeis - veja Importações: Open Finance.

Duas camadas de autorização

Todos os routers usam o _SCOPE_DEP do agregador: escopo derivado do path (tecnospeed:read para GET, tecnospeed:write para POST/PUT/DELETE) mais o gate de senha provisória (JWT de quem ainda está com senha definida por outra pessoa não acessa rotas de dados; API Key não passa por esse gate). Por cima disso, cada rota tem um guard de perfil próprio - e as operações com efeito externo na TecnoSpeed exigem JWT de pessoa (API Key recebe 403). Ter o escopo não basta: veja a coluna "Guard" na tabela abaixo.

Base path

/api/v1/tecnospeed

A URL completa em produção é https://api.contabilidadealcance.com.br/api/v1/tecnospeed.

Escopos e guards

O escopo é derivado do primeiro segmento depois de /api/v1/ (tecnospeed) e do método HTTP. Os guards de perfil são aplicados rota a rota:

GuardQuem passaAPI Key
qualquer funcionárioqualquer usuário interno autenticado (get_current_principal)aceita
funcionário, só pessoaqualquer perfil interno, só com JWT de pessoa (somente_funcionario_humano)403
adm/diretoriaperfis administrador e diretoria (require_perfil)aceita
adm/diretoria, só pessoaadministrador e diretoria, só com JWT de pessoa (somente_gestao_humana)403
administrador, só pessoasó administrador, só com JWT de pessoa (somente_admin_humano)403
RotaEscopoGuard
GET /agendamentostecnospeed:readadministrador, só pessoa
POST /agendamentos, PUT /agendamentos/{agendamento_id}, DELETE /agendamentos/{agendamento_id}tecnospeed:writeadministrador, só pessoa
GET /clientes/{cliente_id}/pagadortecnospeed:readqualquer funcionário
POST /clientes/{cliente_id}/pagador/ativar, .../desativartecnospeed:writeadm/diretoria, só pessoa
GET /clientes/{cliente_id}/bilhetagemtecnospeed:readadm/diretoria
GET /clientes/{cliente_id}/contastecnospeed:readqualquer funcionário
POST /clientes/{cliente_id}/contastecnospeed:writefuncionário, só pessoa
POST .../contas/{conta_id}/consentimentotecnospeed:writeadm/diretoria, só pessoa
DELETE .../contas/{conta_id}tecnospeed:writeadm/diretoria, só pessoa
DELETE .../contas/{conta_id}/expurgartecnospeed:writeadministrador, só pessoa
POST .../contas/{conta_id}/reativar, .../revogartecnospeed:writeadm/diretoria, só pessoa
GET .../contas/{conta_id}/linktecnospeed:readqualquer funcionário
POST .../contas/{conta_id}/enviar-linktecnospeed:writequalquer funcionário (rate limit por IP)
GET .../financeiro/resumo, /transacoes, /transacoes.csv, /protocolostecnospeed:readqualquer funcionário
POST .../financeiro/saldo/atualizar, .../reprocessartecnospeed:writeadm/diretoria, só pessoa

Fluxo

  1. Pagador. POST /clientes/{cliente_id}/pagador/ativar cadastra o cliente como pagador na TecnoSpeed. Só PJ (matriz ou filial) e com o cadastro completo (razão social, bairro, cidade, UF e CEP, entre outros); o que faltar volta em pendencias_cadastro. GET /pagador mostra o estado e as pendências.
  2. Conta. POST /clientes/{cliente_id}/contas cadastra a conta bancária só localmente (desde a 5.283.0): não exige pagador ativo e não chama a TecnoSpeed. A conta nasce com registrada=false, tem_link=false, consentimento pendente e ativo=true.
  3. Consentimento. POST .../contas/{conta_id}/consentimento ("Gerar consentimento") exige o pagador ativo, registra a conta na TecnoSpeed e devolve o openfinance_link. O link pode ser copiado (GET .../link) ou enviado por e-mail ao cliente (POST .../enviar-link). O cliente abre o link e autoriza no banco.
  4. Coleta. A coleta do extrato roda em protocolos: uma rodada fixa diária (hora na configuração TECNOSPEED_RODADA_FIXA_HORA), os agendamentos extras e o reprocessamento manual (POST .../financeiro/reprocessar). A TecnoSpeed impõe intervalo mínimo de 6 horas entre protocolos da mesma conta. A API não recebe o estado do consentimento da TecnoSpeed: ele é inferido - protocolo com sucesso (ou saldo consultado com sucesso) leva a conta de pendente/expirado para ativo; erro de consentimento leva ativo para expirado. revogado só muda por ação humana.
  5. Transações. As transações capturadas são lidas em GET .../financeiro/transacoes (ou transacoes.csv) e resumidas em GET .../financeiro/resumo. A importação para a contabilidade é feita pelo siscontabil em /importacoes/open-finance.

Mudança na 5.283.0: cadastro em dois tempos

Até a 5.282.0, cadastrar a conta já a registrava na TecnoSpeed e devolvia o link (e exigia administrador/diretoria). Desde a 5.283.0, o POST /clientes/{cliente_id}/contas é só local e aberto a qualquer funcionário com JWT de pessoa; o registro na TecnoSpeed (que cria a conta lá e gera custo) virou o passo próprio POST .../consentimento, restrito a administrador/diretoria. O cadastro não devolve mais o link. Conta com registrada=false recebe 409 com code=conta_nao_registrada em revogar e enviar-link, e é ignorada pela rodada automática, pelo reprocessar (409) e pelo "Atualizar saldos".

Erros comuns

Todas as rotas de pagador e contas mapeiam os erros da mesma forma:

StatusQuando
404Cliente inexistente, ou conta_id de outro cliente (não revela que a conta existe).
409Conflito de estado (conta arquivada, pagador inativo, duplicata etc.). Quando há detalhe, detail é um objeto com mensagem e code.
422Validação local ou recusa de validação da TecnoSpeed.
502Qualquer falha vinda da TecnoSpeed (403 de borda, 401, 5xx, timeout), com frase amigável. Nunca é repassada como 401/403, para não ser confundida com a autorização desta API. A falha é registrada na Auditoria como tecnospeed_falha.
503Integração TecnoSpeed não configurada ("Integração TecnoSpeed não configurada.").

Endpoints

GET /tecnospeed/agendamentos

Lista os agendamentos extras de coleta, a hora da rodada fixa e os conflitos com a regra das 6 horas, calculados com a hora fixa atual (um conflito antigo, criado ao mudar a hora fixa, aparece aqui mas não trava a criação de um extra novo válido).

Parâmetros

Este endpoint não recebe parâmetros de rota ou query.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "fixa_hora": 6,
    "extras": [
      {
        "id": 3,
        "hora": 12,
        "alvo": "todos",
        "cliente_id": null,
        "cliente_nome": null,
        "ativo": true,
        "criado_por": 42,
        "created_at": "2026-10-10T09:00:00",
        "updated_at": "2026-10-10T09:00:00"
      }
    ],
    "conflitos": []
  }
}

Escopo: tecnospeed:read (guard: administrador, só pessoa)

POST /tecnospeed/agendamentos

Cria um agendamento extra de coleta. A escrita recusa um horário que fique a menos de 6 horas (medidas de forma circular, 23h para 05h = 6h) de outro horário efetivo da mesma conta, mas só quando o conflito envolve o candidato.

Parâmetros

Sem parâmetros de rota ou query. Corpo AgendamentoEntrada.

Request

{
  "hora": 18,
  "alvo": "cliente",
  "cliente_id": 487,
  "ativo": true
}

Response 201 Created

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "id": 4,
    "hora": 18,
    "alvo": "cliente",
    "cliente_id": 487,
    "cliente_nome": "Empresa Exemplo Ltda",
    "ativo": true,
    "criado_por": 42,
    "created_at": "2026-10-15T10:00:00",
    "updated_at": "2026-10-15T10:00:00"
  }
}

Erros: 422 para conflito com a regra das 6 horas (detail é a lista de mensagens), cliente não encontrado ou corpo inválido (alvo: "cliente" sem cliente_id, ou alvo: "todos" com cliente_id).

Escopo: tecnospeed:write (guard: administrador, só pessoa)

PUT /tecnospeed/agendamentos/{agendamento_id}

Substitui por completo um agendamento extra (mesmo corpo do POST). Pausar (ativo: false) nunca é bloqueado pela regra das 6 horas.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
agendamento_idintpathsimID do agendamento extra.

Request

{
  "hora": 18,
  "alvo": "cliente",
  "cliente_id": 487,
  "ativo": false
}

Response 200 OK

Envelope com o AgendamentoRead atualizado (mesmo formato do POST). 404 se o agendamento não existir; 422 nas mesmas validações do POST.

Escopo: tecnospeed:write (guard: administrador, só pessoa)

DELETE /tecnospeed/agendamentos/{agendamento_id}

Exclui um agendamento extra. Excluir nunca é bloqueado pela regra das 6 horas.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
agendamento_idintpathsimID do agendamento extra.

Request

Sem corpo de requisição.

Response 204 No Content

Sem corpo. 404 se o agendamento não existir.

Escopo: tecnospeed:write (guard: administrador, só pessoa)

GET /tecnospeed/clientes/{cliente_id}/pagador

Estado do pagador do cliente na TecnoSpeed e as pendências do cadastro que impediriam a ativação. A resposta nunca traz o token do pagador.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "ativo": false,
    "ativado_em": null,
    "desativado_em": null,
    "pendencias_cadastro": ["bairro", "CEP"]
  }
}

Escopo: tecnospeed:read (guard: qualquer funcionário)

POST /tecnospeed/clientes/{cliente_id}/pagador/ativar

Cadastra o cliente como pagador na TecnoSpeed. Ordem das validações: cliente existe (404); se já está ativo, devolve o estado sem chamar a TecnoSpeed (idempotente); só PJ (422 "Open Finance só para PJ (matriz ou filial)"); campos obrigatórios do cadastro (422 com detail = {"mensagem": ..., "pendencias": [...]}). Se a TecnoSpeed responder que o pagador já existe, a API reconcilia com o cadastro de lá; se ele estiver inativo na TecnoSpeed, 409. Ao ativar, as contas que tinham sido inativadas pelo desativar (inativada_por: "pagador") voltam a ativo=true.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "ativo": true,
    "ativado_em": "2026-10-15T10:05:00",
    "desativado_em": null,
    "pendencias_cadastro": []
  }
}

Escopo: tecnospeed:write (guard: adm/diretoria, só pessoa)

POST /tecnospeed/clientes/{cliente_id}/pagador/desativar

Desativa o pagador na TecnoSpeed. Idempotente (pagador ausente ou já inativo devolve o estado atual). As contas ativas do cliente ficam ativo=false com inativada_por: "pagador" - sem apagar nem arquivar: o histórico e o consentimento ficam, e a coleta para.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.

Request

Sem corpo de requisição.

Response 200 OK

Envelope com o PagadorEstado (ativo: false, desativado_em preenchido).

Escopo: tecnospeed:write (guard: adm/diretoria, só pessoa)

GET /tecnospeed/clientes/{cliente_id}/bilhetagem

Relatório de bilhetagem (consumo) do pagador na TecnoSpeed no período. Só PJ; período de no máximo 31 dias e date_end não anterior a date_start (422).

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
date_startdatequerysimInício do período (AAAA-MM-DD).
date_enddatequerysimFim do período (AAAA-MM-DD).

Request

Sem corpo de requisição.

Response 200 OK

data é o objeto JSON devolvido pela TecnoSpeed, repassado sem schema próprio desta API (o formato depende da TecnoSpeed).

Escopo: tecnospeed:read (guard: adm/diretoria)

GET /tecnospeed/clientes/{cliente_id}/contas

Lista as contas bancárias do cliente. Contas arquivadas ficam fora por padrão. A listagem não traz o link: traz tem_link e registrada.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
incluir_removidasboolquerynãoInclui as contas arquivadas. Padrão false.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": [
    {
      "id": 7,
      "cliente_id": 487,
      "bank_code": "341",
      "banco_nome": "Banco Itaú",
      "agencia": "1234",
      "agencia_digito": null,
      "numero_conta": "98765",
      "numero_conta_digito": "1",
      "conta_mascarada": "****8765",
      "account_type": null,
      "consentimento_status": "pendente",
      "ativo": true,
      "inativada_por": null,
      "tem_link": false,
      "registrada": false,
      "link_enviado_em": null,
      "saldo": null,
      "saldo_em": null,
      "removida_em": null,
      "created_at": "2026-10-15T10:10:00"
    }
  ]
}

Escopo: tecnospeed:read (guard: qualquer funcionário)

POST /tecnospeed/clientes/{cliente_id}/contas

Cadastra uma conta bancária só localmente (5.283.0): não exige pagador ativo e não chama a TecnoSpeed. A conta nasce com registrada=false, tem_link=false, consentimento pendente e ativo=true; o registro na TecnoSpeed é o POST .../consentimento. A mesma conta (banco, agência e número, dígitos normalizados) no mesmo cliente dá 409 com conta_id; se ela estiver arquivada, o 409 traz code: "conta_arquivada" para o front oferecer "Reativar".

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.

Corpo ContaCreate (campos desconhecidos dão 422).

Request

{
  "bank_code": "341",
  "agencia": "1234",
  "numero_conta": "98765",
  "numero_conta_digito": "1"
}

Response 201 Created

Envelope com o ContaRead da conta criada (mesmo formato de um item da listagem, com registrada: false).

Escopo: tecnospeed:write (guard: funcionário, só pessoa)

POST /tecnospeed/clientes/{cliente_id}/contas/{conta_id}/consentimento

"Gerar consentimento": registra a conta na TecnoSpeed com os dados gravados, grava o identificador da conta lá e o openfinance_link, e devolve a conta com o link. A resposta sai com Cache-Control: no-store.

  • Já registrada com link: idempotente, devolve o estado atual sem chamar a TecnoSpeed.
  • 404 conta de outro cliente ou inexistente.
  • 409 conta arquivada; 409 pagador inativo ({"mensagem": "Ative o Open Finance do cliente primeiro", "code": "pagador_inativo"}); 409 code=registrada_sem_link (o caminho é "Gerar novo link", via revogar).
  • Dois cliques simultâneos não registram a conta duas vezes (a linha fica travada durante o registro).

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
conta_idintpathsimID da conta.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "id": 7,
    "cliente_id": 487,
    "bank_code": "341",
    "banco_nome": "Banco Itaú",
    "agencia": "1234",
    "agencia_digito": null,
    "numero_conta": "98765",
    "numero_conta_digito": "1",
    "conta_mascarada": "****8765",
    "account_type": null,
    "consentimento_status": "pendente",
    "ativo": true,
    "inativada_por": null,
    "tem_link": true,
    "registrada": true,
    "link_enviado_em": null,
    "saldo": null,
    "saldo_em": null,
    "removida_em": null,
    "created_at": "2026-10-15T10:10:00",
    "openfinance_link": "https://exemplo.tecnospeed.com.br/consentimento/abc123"
  }
}

Escopo: tecnospeed:write (guard: adm/diretoria, só pessoa)

DELETE /tecnospeed/clientes/{cliente_id}/contas/{conta_id}

"Remover conta": arquiva, não apaga. Marca ativo=false, inativada_por: "arquivada" e removida_em; a linha e o histórico (protocolos e transações) ficam. Se a conta está registrada e o pagador ativo, remove a conta também na TecnoSpeed (se ela já não existir lá, arquiva só aqui). Conta nunca registrada ou com pagador inativo é arquivada só aqui. Idempotente para conta já arquivada.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
conta_idintpathsimID da conta.

Request

Sem corpo de requisição.

Response 200 OK

Envelope com o ContaRead arquivado.

Escopo: tecnospeed:write (guard: adm/diretoria, só pessoa)

DELETE /tecnospeed/clientes/{cliente_id}/contas/{conta_id}/expurgar

Apaga de vez a linha de uma conta já arquivada (409 se não estiver). Se já houver transações dessa conta lançadas na contabilidade (importação Open Finance), o banco barra a exclusão e a rota responde 409.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
conta_idintpathsimID da conta.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "id": 7,
    "expurgada": true
  }
}

Escopo: tecnospeed:write (guard: administrador, só pessoa)

POST /tecnospeed/clientes/{cliente_id}/contas/{conta_id}/reativar

Desarquiva a mesma linha (nunca cria uma segunda). Só conta arquivada (409 nas outras). Conta registrada exige pagador ativo (409 code=pagador_inativo) e é registrada de novo na TecnoSpeed; se a TecnoSpeed devolver outro identificador, a mesma linha é atualizada. Conta arquivada que nunca foi registrada é desarquivada só aqui, sem pagador e sem chamar a TecnoSpeed. A conta volta com consentimento pendente.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
conta_idintpathsimID da conta.

Request

Sem corpo de requisição.

Response 200 OK

Envelope com o ContaRead reativado.

Escopo: tecnospeed:write (guard: adm/diretoria, só pessoa)

POST /tecnospeed/clientes/{cliente_id}/contas/{conta_id}/revogar

Revoga o consentimento na TecnoSpeed. Com desabilitar: false (padrão) é o "Gerar novo link": o consentimento volta a pendente com o link novo, se vier, e uma conta antes desconectada volta a ativo=true. Com desabilitar: true é o "Desconectar": consentimento revogado, ativo=false, inativada_por: "desconectada" e o link é apagado. Exige conta não arquivada (409), registrada (409 code=conta_nao_registrada) e pagador ativo (409 code=pagador_inativo).

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
conta_idintpathsimID da conta.

Corpo RevogarBody opcional.

Request

{
  "desabilitar": false
}

Response 200 OK

Envelope com o ContaRead atualizado.

Escopo: tecnospeed:write (guard: adm/diretoria, só pessoa)

Devolve o link de consentimento da conta ("copiar link"). Ao lado da resposta do POST .../consentimento, é a única rota que devolve o link em JSON. openfinance_link é null quando a conta não tem link.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
conta_idintpathsimID da conta.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "openfinance_link": "https://exemplo.tecnospeed.com.br/consentimento/abc123"
  }
}

Escopo: tecnospeed:read (guard: qualquer funcionário)

POST /tecnospeed/clientes/{cliente_id}/contas/{conta_id}/enviar-link

Envia o link de consentimento por e-mail. Sem email no corpo, usa o e-mail do cadastro do cliente (422 se não houver). Exige conta não arquivada, registrada (409 code=conta_nao_registrada) e com link (409). O envio é best-effort: falha de SMTP responde 200 com email_enviado: false. Limite de 10 envios por minuto por IP.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
conta_idintpathsimID da conta.

Corpo EnviarLinkBody opcional.

Request

{
  "email": "financeiro@empresa-exemplo.com.br"
}

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "email_enviado": true,
    "destino_mascarado": "fi***@empresa-exemplo.com.br",
    "mensagem": "Link enviado para fi***@empresa-exemplo.com.br"
  }
}

Escopo: tecnospeed:write (guard: qualquer funcionário)

GET /tecnospeed/clientes/{cliente_id}/financeiro/resumo

Resumo financeiro do cliente no período: contas com saldo, saldo total, entradas, saídas, resultado e a última captura. O escopo inclui as contas da matriz e das filiais da mesma raiz. Sem inicio/fim, o período é o mês corrente (horário de São Paulo); com só uma ponta, a outra é o limite do mês dela. Período máximo de 366 dias (422).

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
iniciodatequerynãoInício do período.
fimdatequerynãoFim do período.
incluir_removidasboolquerynãoInclui contas arquivadas. Padrão false.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "contas": [
      {
        "id": 7,
        "cliente_id": 487,
        "empresa": "Empresa Exemplo Ltda",
        "bank_code": "341",
        "banco_nome": "Banco Itaú",
        "agencia": "1234",
        "conta_mascarada": "****8765",
        "consentimento_status": "ativo",
        "ativo": true,
        "inativada_por": null,
        "removida_em": null,
        "saldo": "15230.45",
        "saldo_em": "2026-10-15T06:05:00"
      }
    ],
    "saldo_total": "15230.45",
    "saldo_total_em": "2026-10-15T06:05:00",
    "entradas": "42000.00",
    "saidas": "31890.10",
    "resultado": "10109.90",
    "ultima_captura": "2026-10-15T06:05:00",
    "inicio": "2026-10-01",
    "fim": "2026-10-31"
  }
}

Valores monetários saem como string (nunca float). 404 para cliente inexistente.

Escopo: tecnospeed:read (guard: qualquer funcionário)

GET /tecnospeed/clientes/{cliente_id}/financeiro/transacoes

Transações capturadas no período, paginadas. conta_id fora do escopo do cliente responde 404 sem revelar que a conta existe.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
iniciodatequerynãoInício do período (padrão: mês corrente).
fimdatequerynãoFim do período.
conta_idintquerynãoFiltra uma conta.
naturezastrquerynãoC (crédito) ou D (débito).
buscastrquerynãoBusca na descrição ou na contraparte (até 100 caracteres; acima, 422).
paginaintquerynãoPágina (>= 1). Padrão 1.
por_paginaintquerynãoItens por página. Padrão 50; teto 100.
incluir_removidasboolquerynãoInclui contas arquivadas. Padrão false.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "itens": [
      {
        "id": 9001,
        "conta_id": 7,
        "empresa": "Empresa Exemplo Ltda",
        "data": "2026-10-14",
        "descricao": "PIX RECEBIDO",
        "contraparte_nome": "Cliente Exemplo",
        "contraparte_documento_mascarado": null,
        "valor": "1500.00",
        "natureza": "C",
        "categoria": null
      }
    ],
    "total": 1,
    "pagina": 1,
    "por_pagina": 50
  }
}

Escopo: tecnospeed:read (guard: qualquer funcionário)

GET /tecnospeed/clientes/{cliente_id}/financeiro/transacoes.csv

As mesmas transações (mesmos filtros, sem paginação) em CSV: separador ;, BOM UTF-8, valor com vírgula decimal, data dd/mm/aaaa, conta mascarada e sem o documento da contraparte. Colunas: data, empresa, conta, descricao, contraparte, natureza, valor. Texto que começa com =, +, -, @, TAB ou CR é prefixado com ' (proteção contra CSV injection). Arquivo transacoes_{cliente_id}_{AAAAMMDD}_{AAAAMMDD}.csv. Acima de 10.000 linhas, 422 pedindo um período menor.

Parâmetros

Os mesmos de GET .../financeiro/transacoes, exceto pagina e por_pagina.

Request

Sem corpo de requisição.

Response 200 OK

Arquivo CSV (não é envelope JSON).

Escopo: tecnospeed:read (guard: qualquer funcionário)

GET /tecnospeed/clientes/{cliente_id}/financeiro/protocolos

Protocolos de coleta (pedidos de extrato à TecnoSpeed) das contas do cliente, paginados.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.
paginaintquerynãoPágina (>= 1). Padrão 1.
por_paginaintquerynãoItens por página. Padrão 50; teto 100.
incluir_removidasboolquerynãoInclui contas arquivadas. Padrão false.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "itens": [
      {
        "id": 310,
        "conta_id": 7,
        "empresa": "Empresa Exemplo Ltda",
        "data_inicio": "2026-10-14",
        "data_fim": "2026-10-14",
        "origem": "fixa",
        "status": "concluido",
        "motivo": null,
        "total_transacoes": 12,
        "transacoes_descartadas": 0,
        "status_tecnospeed": "SUCCESS",
        "agendamento_id": null,
        "criado_em": "2026-10-15T06:00:00",
        "concluido_em": "2026-10-15T06:04:00"
      }
    ],
    "total": 1,
    "pagina": 1,
    "por_pagina": 50
  }
}

origem: fixa, extra ou manual. status: pendente, processando, concluido, falha ou pulado_janela.

Escopo: tecnospeed:read (guard: qualquer funcionário)

POST /tecnospeed/clientes/{cliente_id}/financeiro/saldo/atualizar

"Atualizar saldos": consulta na TecnoSpeed o saldo de cada conta ativa do cliente. Best-effort por conta: a falha de uma conta vem no item dela (erro) e as outras seguem; a rota nunca dá 500 por uma conta. Conta não registrada recebe "Gere o consentimento da conta primeiro.". Há um cooldown de 120 segundos por cliente: dentro dele, 409 com {"mensagem": ..., "proxima_em": ...}.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Operação realizada com sucesso",
  "data": {
    "contas": [
      {
        "conta_id": 7,
        "saldo": "15230.45",
        "saldo_em": "2026-10-15T10:20:00",
        "erro": null
      },
      {
        "conta_id": 8,
        "saldo": null,
        "saldo_em": null,
        "erro": "Consentimento Open Finance expirado ou ausente: gere um novo link para o cliente."
      }
    ]
  }
}

Escopo: tecnospeed:write (guard: adm/diretoria, só pessoa)

POST /tecnospeed/clientes/{cliente_id}/financeiro/reprocessar

Pede manualmente à TecnoSpeed o extrato de uma conta num período (cria um protocolo de origem manual). fim não pode passar de hoje no horário de São Paulo (422), e o período segue o limite de 366 dias.

Respostas de erro:

  • 404 cliente inexistente ou conta fora do escopo do cliente.
  • 409 dentro da janela de 6 horas da conta: {"mensagem": "Próxima consulta possível às HH:MM", "proxima_em": ...}.
  • 409 conta inativa, consentimento revogado, pagador inativo ou conta não registrada ({"mensagem": ...}).

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
cliente_idintpathsimID do cliente.

Corpo ReprocessarEntrada (campos desconhecidos dão 422).

Request

{
  "conta_id": 7,
  "inicio": "2026-10-01",
  "fim": "2026-10-14"
}

Response 202 Accepted

Envelope com o ProtocoloRead criado (mesmo formato de um item de GET .../financeiro/protocolos). O 202 também vale quando o protocolo foi gravado com falha na solicitação: o front deve exibir o status e o motivo.

Escopo: tecnospeed:write (guard: adm/diretoria, só pessoa)

Schemas

AgendamentoEntrada

Corpo de POST e PUT /agendamentos (substituição completa). Campos desconhecidos dão 422.

CampoTipoObrigatórioObservações
horaintsimHora do dia, de 0 a 23.
alvostrsimtodos ou cliente.
cliente_idintcondicionalObrigatório com alvo: "cliente"; proibido com todos.
ativoboolnãoPadrão true.

AgendamentosResposta

CampoTipoObservações
fixa_horaintHora da rodada fixa (TECNOSPEED_RODADA_FIXA_HORA).
extraslist[AgendamentoRead]id, hora, alvo, cliente_id, cliente_nome, ativo, criado_por, created_at, updated_at.
conflitoslistCada item: mensagem, cliente_id, agendamento_ids.

PagadorEstado

CampoTipoObservações
ativoboolPagador ativo na integração.
ativado_emdatetimePode ser null.
desativado_emdatetimePode ser null.
pendencias_cadastrolist[str]Campos do cadastro do cliente que impedem a ativação.

ContaCreate

CampoTipoObrigatórioObservações
bank_codestrsimCódigo FEBRABAN aceito pela TecnoSpeed (veja a lista abaixo).
agenciastrsimSó dígitos, 1 a 10 caracteres.
agencia_digitostrnãoAté 2 caracteres: dígito ou X.
numero_contastrsimSó dígitos, 1 a 12 caracteres.
numero_conta_digitostrnãoAté 2 caracteres: dígito ou X.
account_typeintnão0 a 32767; só vale para a Caixa (104).

Bancos aceitos em bank_code: 001 Banco do Brasil, 004 Banco do Nordeste do Brasil, 033 Banco Santander, 041 Banco Banrisul, 070 Banco BRB, 077 Banco Inter, 104 Caixa Econômica Federal, 136 Banco Unicred, 208 BTG Pactual, 237 Banco Bradesco, 318 Banco BMG, 329 Banco QI Tech, 341 Banco Itaú, 365 K8 Fintech, 422 Banco Safra, 745 Banco Citibank, 748 Banco Sicredi, 755 Bank Of America, 756 Banco Sicoob.

ContaRead

Nunca carrega o link nem o identificador da conta na TecnoSpeed.

CampoTipoObservações
idintID da conta.
cliente_idintID do cliente.
bank_codestrCódigo do banco.
banco_nomestrNome do banco. Pode ser null.
agenciastrAgência.
agencia_digitostrPode ser null.
numero_contastrNúmero da conta.
numero_conta_digitostrPode ser null.
conta_mascaradastrÚltimos 4 dígitos, ex. ****8765.
account_typeintPode ser null.
consentimento_statusstrpendente, ativo, revogado ou expirado.
ativoboolConta ativa na coleta.
inativada_porstrMotivo do ativo=false: pagador, desconectada ou arquivada.
tem_linkboolHá link de consentimento gravado.
registradaboolfalse = só cadastrada aqui; o "Gerar consentimento" a registra na TecnoSpeed (5.283.0).
link_enviado_emdatetimeÚltimo envio do link por e-mail.
saldodecimalÚltimo saldo consultado (string no JSON).
saldo_emdatetimeMomento do saldo.
removida_emdatetimePreenchido quando arquivada.
created_atdatetimeCriação.

A resposta do POST .../consentimento é o ContaRead com o campo extra openfinance_link.

Cada motivo de inativada_por tem um único caminho de volta:

inativada_porComo chegaComo volta
pagadorPOST .../pagador/desativarPOST .../pagador/ativar
desconectadaPOST .../revogar com desabilitar: truePOST .../revogar com desabilitar: false
arquivadaDELETE .../contas/{conta_id}POST .../contas/{conta_id}/reativar

RevogarBody e EnviarLinkBody

SchemaCampoTipoObservações
RevogarBodydesabilitarboolfalse (padrão) = "Gerar novo link"; true = "Desconectar".
EnviarLinkBodyemailstrE-mail de destino. Ausente = e-mail do cadastro do cliente.

ResumoFinanceiro

CampoTipoObservações
contaslist[ContaFinanceiroResumo]id, cliente_id, empresa, bank_code, banco_nome, agencia, conta_mascarada, consentimento_status, ativo, inativada_por, removida_em, saldo, saldo_em.
saldo_totaldecimalPode ser null.
saldo_total_emdatetimeO snapshot mais antigo entre as contas com saldo.
entradasdecimalSoma dos créditos no período.
saidasdecimalSoma dos débitos no período.
resultadodecimalResultado do período.
ultima_capturadatetimePode ser null.
inicio, fimdatePeríodo efetivamente aplicado.

TransacaoRead

CampoTipoObservações
idintID da transação.
conta_idintConta de origem.
empresastrRazão social da empresa da conta.
datadateData da transação.
descricaostrDescrição vinda do banco.
contraparte_nomestrPode ser null.
contraparte_documento_mascaradostrDocumento da contraparte mascarado.
valordecimalString no JSON.
naturezastrC ou D.
categoriastrPode ser null.

ProtocoloRead

CampoTipoObservações
idintID do protocolo.
conta_idintConta consultada.
empresastrRazão social da empresa da conta.
data_inicio, data_fimdatePeríodo pedido.
origemstrfixa, extra ou manual.
statusstrpendente, processando, concluido, falha ou pulado_janela.
motivostrMotivo da falha, quando houver.
total_transacoesintPode ser null.
transacoes_descartadasintTransações postas em quarentena.
status_tecnospeedstrStatus bruto da TecnoSpeed. Pode ser null.
agendamento_idintAgendamento extra que gerou o protocolo, se houver.
criado_emdatetimeCriação.
concluido_emdatetimePode ser null.

ReprocessarEntrada

CampoTipoObrigatórioObservações
conta_idintsim>= 1.
iniciodatesimInício do período.
fimdatesimNão pode passar de hoje (São Paulo).

ResultadoSaldos

CampoTipoObservações
contaslist[SaldoDaConta]Cada item: conta_id, saldo, saldo_em e erro (preenchido só quando a conta falhou).

Notas

  • Nenhuma resposta carrega o token do pagador. As mensagens de erro da TecnoSpeed chegam com token e documentos mascarados.
  • O schema do financeiro é um contrato compartilhado entre Hub, siscontabil e Portal do Cliente: mudar um campo exige mudar os três fronts no mesmo trem.
  • O Portal do Cliente lê o financeiro por rotas próprias do realm do Portal, fora deste prefixo (não documentadas nesta página).