Ponte TOConline

Integrar com a Ponte

Troca a sua chave API por um token de acesso do TOConline. Três passos, e a partir daí fala directamente com a API deles.

O token é usado contra o TOConline, não contra a ponte. A ponte entrega a chave e sai da frente; os seus dados nunca passam por aqui.
O endereço da API varia de empresa para empresa. O TOConline distribui-as por servidores diferentes. Nunca fixe o api_url no código — use o que vem no passo 1.

Os exemplos usam https://ponte.exemplo.pt — substitua pelo endereço que lhe foi dado com a chave. · Não sabe o que é a ponte? Comece pelo início.

Os três passos

Precisa de uma chave API, que lhe é entregue uma única vez quando o seu acesso é criado. Guarde-a: não há forma de a recuperar.

Ponte guarda as credenciais A sua aplicação tem uma chave API TOConline a API da empresa 1 POST /v1/auth e depois /v1/token 2 access_token + api_url com a hora a que expira 3 os dados, com o token e é aqui que está o trabalho todo mantém a integração registada a ponte aparece nos passos 1 e 2. O 3 não passa por lá.
01

Autenticar-se e descobrir as empresas

Troca a chave por um token de sessão de 15 minutos e recebe a lista de empresas a que tem acesso, cada uma com o seu api_url.

POST /v1/auth
X-Api-Key: ak_live_…
{
  "token": "bt_…",
  "expires_at": "2026-08-27T11:05:00.000Z",
  "companies": [
    {
      "nif": "515921262",
      "name": "Bizzpm, Lda",
      "api_url": "https://api11.toconline.pt"
    }
  ]
}
02

Pedir o token de acesso

Indique o NIF da empresa. Recebe um access_token do TOConline e o instante real em que expira — não uma duração nominal.

POST /v1/token
Authorization: Bearer bt_…
Content-Type: application/json

{ "nif": "515921262" }
{
  "access_token": "11-140905-…",
  "expires_at": "2026-08-27T14:58:12.000Z",
  "api_url": "https://api11.toconline.pt"
}
03

Falar com o TOConline

Use o token no Authorization contra o api_url que recebeu. A partir daqui é a API do TOConline — os recursos e os filtros estão documentados por eles.

GET {api_url}/api/commercial_sales_documents?page[size]=5
Authorization: Bearer 11-140905-…
Accept: application/json

Referência

O contrato completo, para quem está a escrever o cliente.

O que vem em cada resposta

CampoOndeO que é
tokenpasso 1 Token de sessão da ponte (bt_…). Serve para chamar o passo 2, e mais nada. Vive 15 minutos.
companies[]passo 1 nif, name e api_url de cada empresa a que tem acesso. Só essas.
access_tokenpasso 2 Token do TOConline. É este que usa contra a API deles.
expires_atpassos 1 e 2 Instante em que deixa de servir, em ISO 8601 UTC. É o tempo real que resta, não uma duração nominal.
api_urlpasso 2 Endereço da API para aquela empresa.

Boas práticas

Guarde o token até expirar É o mais importante desta página. Peça um access_token, use-o em todos os pedidos até ao expires_at, e só então peça outro. Chamar o passo 2 antes de cada pedido funciona — a ponte serve do que tem — mas acrescenta uma ida e volta a tudo o que a sua aplicação faz.
Renove com folga Peça um token novo alguns minutos antes do expires_at, não no instante exacto. Um pedido em curso não deve apanhar a expiração a meio.
Não precisa de serializar Vários pedidos simultâneos para a mesma empresa não geram várias autorizações: a ponte junta-os e responde a todos com o mesmo token.
Um token por empresa O access_token vale para a empresa que pediu. Com várias empresas, guarde um por NIF.

Renovação

Não precisa de renovar nada. A ponte mantém o token vivo sozinha e nunca lho entrega perto de expirar. Se repetir o POST /v1/token, recebe o token em vigor — a menos que falte menos de 2 minutos para expirar, caso em que é cunhado um novo. Guarde o último token válido: se a ponte estiver indisponível por instantes, o que tem em mãos continua a servir.

Quando a sessão dos 15 minutos acaba

O token do passo 1 é curto de propósito: a sua fuga não vale grande coisa. Se expirar a meio de um lote, o passo 2 devolve 401 — repita o passo 1 e continue. Não precisa de pedir tokens de acesso novos: os que já tem continuam válidos até ao expires_at deles.

Revogar a chave API corta o acesso de imediato, mesmo dentro dos 15 minutos: a sessão é revalidada em cada passo 2.

Erros

CódigoQuando aconteceO que fazer
400Falta o nif, ou não tem 9 dígitos Corrigir o pedido
401Chave inválida ou revogada, ou token de sessão expirado Repetir o passo 1; se persistir, a chave foi revogada
403Não tem acesso a essa empresa Pedir a concessão a quem administra a ponte
429Demasiadas tentativas de autenticação Esperar e repetir
502O TOConline recusou ou não respondeu Repetir mais tarde; a mensagem indica a causa quando é seguro indicá-la

A ter em conta

O api_url varia por empresa Não o fixe no código. Use o que vem no passo 1 ou no passo 2.
O expires_at é o tempo real É o instante em que o token deixa de servir, não “agora mais quatro horas”.
A chave é mostrada uma vez Só o prefixo fica registado. Perdida, tem de ser emitida outra.
O acesso é por empresa Pedir um NIF sem concessão devolve 403, exista essa empresa ou não.
Um 502 que persiste não é seu Significa que o TOConline recusou as credenciais daquela empresa — tipicamente porque o segredo foi rodado lá. Repetir não resolve; fale com quem administra a ponte.
O NIF tem 9 dígitos Qualquer outra coisa devolve 400 antes de chegar ao TOConline.

Exemplos

Os três passos, de ponta a ponta.

curl

# 1 — sessão + empresas
curl -s -X POST https://ponte.exemplo.pt/v1/auth \
  -H "X-Api-Key: $CHAVE"

# 2 — token de acesso
curl -s -X POST https://ponte.exemplo.pt/v1/token \
  -H "Authorization: Bearer $SESSAO" \
  -H "Content-Type: application/json" \
  -d '{"nif":"515921262"}'

# 3 — TOConline, directamente
curl -s -g "$API_URL/api/commercial_sales_documents?page[size]=5" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"

Node

const PONTE = 'https://ponte.exemplo.pt'

async function tokenPara(nif) {
  // 1 — sessao de 15 minutos + lista de empresas
  const s = await fetch(PONTE + '/v1/auth', {
    method: 'POST',
    headers: { 'X-Api-Key': process.env.PONTE_API_KEY },
  })
  if (!s.ok) throw new Error('chave API recusada')
  const sessao = await s.json()

  // 2 — token de acesso para uma empresa
  const r = await fetch(PONTE + '/v1/token', {
    method: 'POST',
    headers: {
      Authorization: 'Bearer ' + sessao.token,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ nif }),
  })
  if (!r.ok) throw new Error((await r.json()).message)

  // { access_token, expires_at, api_url }
  // O api_url vem daqui: nao o fixe no codigo.
  return r.json()
}

Os recursos, os filtros e os formatos dos documentos são do TOConline. A ponte trata do acesso; o resto está documentado por eles.

Documentação do TOConline ↗