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/tecnospeedA 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:
| Guard | Quem passa | API Key |
|---|---|---|
| qualquer funcionário | qualquer usuário interno autenticado (get_current_principal) | aceita |
| funcionário, só pessoa | qualquer perfil interno, só com JWT de pessoa (somente_funcionario_humano) | 403 |
| adm/diretoria | perfis administrador e diretoria (require_perfil) | aceita |
| adm/diretoria, só pessoa | administrador e diretoria, só com JWT de pessoa (somente_gestao_humana) | 403 |
| administrador, só pessoa | só administrador, só com JWT de pessoa (somente_admin_humano) | 403 |
| Rota | Escopo | Guard |
|---|---|---|
GET /agendamentos | tecnospeed:read | administrador, só pessoa |
POST /agendamentos, PUT /agendamentos/{agendamento_id}, DELETE /agendamentos/{agendamento_id} | tecnospeed:write | administrador, só pessoa |
GET /clientes/{cliente_id}/pagador | tecnospeed:read | qualquer funcionário |
POST /clientes/{cliente_id}/pagador/ativar, .../desativar | tecnospeed:write | adm/diretoria, só pessoa |
GET /clientes/{cliente_id}/bilhetagem | tecnospeed:read | adm/diretoria |
GET /clientes/{cliente_id}/contas | tecnospeed:read | qualquer funcionário |
POST /clientes/{cliente_id}/contas | tecnospeed:write | funcionário, só pessoa |
POST .../contas/{conta_id}/consentimento | tecnospeed:write | adm/diretoria, só pessoa |
DELETE .../contas/{conta_id} | tecnospeed:write | adm/diretoria, só pessoa |
DELETE .../contas/{conta_id}/expurgar | tecnospeed:write | administrador, só pessoa |
POST .../contas/{conta_id}/reativar, .../revogar | tecnospeed:write | adm/diretoria, só pessoa |
GET .../contas/{conta_id}/link | tecnospeed:read | qualquer funcionário |
POST .../contas/{conta_id}/enviar-link | tecnospeed:write | qualquer funcionário (rate limit por IP) |
GET .../financeiro/resumo, /transacoes, /transacoes.csv, /protocolos | tecnospeed:read | qualquer funcionário |
POST .../financeiro/saldo/atualizar, .../reprocessar | tecnospeed:write | adm/diretoria, só pessoa |
Fluxo
- Pagador.
POST /clientes/{cliente_id}/pagador/ativarcadastra 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 empendencias_cadastro.GET /pagadormostra o estado e as pendências. - Conta.
POST /clientes/{cliente_id}/contascadastra 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 comregistrada=false,tem_link=false, consentimentopendenteeativo=true. - Consentimento.
POST .../contas/{conta_id}/consentimento("Gerar consentimento") exige o pagador ativo, registra a conta na TecnoSpeed e devolve oopenfinance_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. - 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 dependente/expiradoparaativo; erro de consentimento levaativoparaexpirado.revogadosó muda por ação humana. - Transações. As transações capturadas são lidas em
GET .../financeiro/transacoes(outransacoes.csv) e resumidas emGET .../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:
| Status | Quando |
|---|---|
404 | Cliente inexistente, ou conta_id de outro cliente (não revela que a conta existe). |
409 | Conflito de estado (conta arquivada, pagador inativo, duplicata etc.). Quando há detalhe, detail é um objeto com mensagem e code. |
422 | Validação local ou recusa de validação da TecnoSpeed. |
502 | Qualquer 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. |
503 | Integraçã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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
agendamento_id | int | path | sim | ID 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
agendamento_id | int | path | sim | ID 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
date_start | date | query | sim | Início do período (AAAA-MM-DD). |
date_end | date | query | sim | Fim 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
incluir_removidas | bool | query | não | Inclui 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID 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.
404conta de outro cliente ou inexistente.409conta arquivada;409pagador inativo ({"mensagem": "Ative o Open Finance do cliente primeiro", "code": "pagador_inativo"});409code=registrada_sem_link(o caminho é "Gerar novo link", viarevogar).- Dois cliques simultâneos não registram a conta duas vezes (a linha fica travada durante o registro).
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
conta_id | int | path | sim | ID 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
conta_id | int | path | sim | ID 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
conta_id | int | path | sim | ID 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
conta_id | int | path | sim | ID 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
conta_id | int | path | sim | ID da conta. |
Corpo RevogarBody opcional.
Request
{
"desabilitar": false
}Response 200 OK
Envelope com o ContaRead atualizado.
Escopo: tecnospeed:write (guard: adm/diretoria, só pessoa)
GET /tecnospeed/clientes/{cliente_id}/contas/{conta_id}/link
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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
conta_id | int | path | sim | ID 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
conta_id | int | path | sim | ID 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
inicio | date | query | não | Início do período. |
fim | date | query | não | Fim do período. |
incluir_removidas | bool | query | não | Inclui 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
inicio | date | query | não | Início do período (padrão: mês corrente). |
fim | date | query | não | Fim do período. |
conta_id | int | query | não | Filtra uma conta. |
natureza | str | query | não | C (crédito) ou D (débito). |
busca | str | query | não | Busca na descrição ou na contraparte (até 100 caracteres; acima, 422). |
pagina | int | query | não | Página (>= 1). Padrão 1. |
por_pagina | int | query | não | Itens por página. Padrão 50; teto 100. |
incluir_removidas | bool | query | não | Inclui 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID do cliente. |
pagina | int | query | não | Página (>= 1). Padrão 1. |
por_pagina | int | query | não | Itens por página. Padrão 50; teto 100. |
incluir_removidas | bool | query | não | Inclui 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âmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID 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:
404cliente inexistente ou conta fora do escopo do cliente.409dentro da janela de 6 horas da conta:{"mensagem": "Próxima consulta possível às HH:MM", "proxima_em": ...}.409conta inativa, consentimento revogado, pagador inativo ou conta não registrada ({"mensagem": ...}).
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cliente_id | int | path | sim | ID 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.
| Campo | Tipo | Obrigatório | Observações |
|---|---|---|---|
hora | int | sim | Hora do dia, de 0 a 23. |
alvo | str | sim | todos ou cliente. |
cliente_id | int | condicional | Obrigatório com alvo: "cliente"; proibido com todos. |
ativo | bool | não | Padrão true. |
AgendamentosResposta
| Campo | Tipo | Observações |
|---|---|---|
fixa_hora | int | Hora da rodada fixa (TECNOSPEED_RODADA_FIXA_HORA). |
extras | list[AgendamentoRead] | id, hora, alvo, cliente_id, cliente_nome, ativo, criado_por, created_at, updated_at. |
conflitos | list | Cada item: mensagem, cliente_id, agendamento_ids. |
PagadorEstado
| Campo | Tipo | Observações |
|---|---|---|
ativo | bool | Pagador ativo na integração. |
ativado_em | datetime | Pode ser null. |
desativado_em | datetime | Pode ser null. |
pendencias_cadastro | list[str] | Campos do cadastro do cliente que impedem a ativação. |
ContaCreate
| Campo | Tipo | Obrigatório | Observações |
|---|---|---|---|
bank_code | str | sim | Código FEBRABAN aceito pela TecnoSpeed (veja a lista abaixo). |
agencia | str | sim | Só dígitos, 1 a 10 caracteres. |
agencia_digito | str | não | Até 2 caracteres: dígito ou X. |
numero_conta | str | sim | Só dígitos, 1 a 12 caracteres. |
numero_conta_digito | str | não | Até 2 caracteres: dígito ou X. |
account_type | int | não | 0 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.
| Campo | Tipo | Observações |
|---|---|---|
id | int | ID da conta. |
cliente_id | int | ID do cliente. |
bank_code | str | Código do banco. |
banco_nome | str | Nome do banco. Pode ser null. |
agencia | str | Agência. |
agencia_digito | str | Pode ser null. |
numero_conta | str | Número da conta. |
numero_conta_digito | str | Pode ser null. |
conta_mascarada | str | Últimos 4 dígitos, ex. ****8765. |
account_type | int | Pode ser null. |
consentimento_status | str | pendente, ativo, revogado ou expirado. |
ativo | bool | Conta ativa na coleta. |
inativada_por | str | Motivo do ativo=false: pagador, desconectada ou arquivada. |
tem_link | bool | Há link de consentimento gravado. |
registrada | bool | false = só cadastrada aqui; o "Gerar consentimento" a registra na TecnoSpeed (5.283.0). |
link_enviado_em | datetime | Último envio do link por e-mail. |
saldo | decimal | Último saldo consultado (string no JSON). |
saldo_em | datetime | Momento do saldo. |
removida_em | datetime | Preenchido quando arquivada. |
created_at | datetime | Criaçã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_por | Como chega | Como volta |
|---|---|---|
pagador | POST .../pagador/desativar | POST .../pagador/ativar |
desconectada | POST .../revogar com desabilitar: true | POST .../revogar com desabilitar: false |
arquivada | DELETE .../contas/{conta_id} | POST .../contas/{conta_id}/reativar |
RevogarBody e EnviarLinkBody
| Schema | Campo | Tipo | Observações |
|---|---|---|---|
RevogarBody | desabilitar | bool | false (padrão) = "Gerar novo link"; true = "Desconectar". |
EnviarLinkBody | email | str | E-mail de destino. Ausente = e-mail do cadastro do cliente. |
ResumoFinanceiro
| Campo | Tipo | Observações |
|---|---|---|
contas | list[ContaFinanceiroResumo] | id, cliente_id, empresa, bank_code, banco_nome, agencia, conta_mascarada, consentimento_status, ativo, inativada_por, removida_em, saldo, saldo_em. |
saldo_total | decimal | Pode ser null. |
saldo_total_em | datetime | O snapshot mais antigo entre as contas com saldo. |
entradas | decimal | Soma dos créditos no período. |
saidas | decimal | Soma dos débitos no período. |
resultado | decimal | Resultado do período. |
ultima_captura | datetime | Pode ser null. |
inicio, fim | date | Período efetivamente aplicado. |
TransacaoRead
| Campo | Tipo | Observações |
|---|---|---|
id | int | ID da transação. |
conta_id | int | Conta de origem. |
empresa | str | Razão social da empresa da conta. |
data | date | Data da transação. |
descricao | str | Descrição vinda do banco. |
contraparte_nome | str | Pode ser null. |
contraparte_documento_mascarado | str | Documento da contraparte mascarado. |
valor | decimal | String no JSON. |
natureza | str | C ou D. |
categoria | str | Pode ser null. |
ProtocoloRead
| Campo | Tipo | Observações |
|---|---|---|
id | int | ID do protocolo. |
conta_id | int | Conta consultada. |
empresa | str | Razão social da empresa da conta. |
data_inicio, data_fim | date | Período pedido. |
origem | str | fixa, extra ou manual. |
status | str | pendente, processando, concluido, falha ou pulado_janela. |
motivo | str | Motivo da falha, quando houver. |
total_transacoes | int | Pode ser null. |
transacoes_descartadas | int | Transações postas em quarentena. |
status_tecnospeed | str | Status bruto da TecnoSpeed. Pode ser null. |
agendamento_id | int | Agendamento extra que gerou o protocolo, se houver. |
criado_em | datetime | Criação. |
concluido_em | datetime | Pode ser null. |
ReprocessarEntrada
| Campo | Tipo | Obrigatório | Observações |
|---|---|---|---|
conta_id | int | sim | >= 1. |
inicio | date | sim | Início do período. |
fim | date | sim | Não pode passar de hoje (São Paulo). |
ResultadoSaldos
| Campo | Tipo | Observações |
|---|---|---|
contas | list[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).