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.
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.
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.
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"
}
]
}
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"
}
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
O contrato completo, para quem está a escrever o cliente.
| Campo | Onde | O que é |
|---|---|---|
token | passo 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_token | passo 2 | Token do TOConline. É este que usa contra a API deles. |
expires_at | passos 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_url | passo 2 | Endereço da API para aquela empresa. |
| 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. |
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.
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.
| Código | Quando acontece | O que fazer |
|---|---|---|
400 | Falta o nif, ou não tem 9 dígitos |
Corrigir o pedido |
401 | Chave inválida ou revogada, ou token de sessão expirado | Repetir o passo 1; se persistir, a chave foi revogada |
403 | Não tem acesso a essa empresa | Pedir a concessão a quem administra a ponte |
429 | Demasiadas tentativas de autenticação | Esperar e repetir |
502 | O TOConline recusou ou não respondeu | Repetir mais tarde; a mensagem indica a causa quando é seguro indicá-la |
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. |
Os três passos, de ponta a ponta.
# 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"
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 ↗