watchOrders
Receba atualizações em tempo real sobre o status das ordens de compra e venda.
Subscrição
{
"action": "subscribe",
"channel": "watchOrders"
}
Payload de Dados
Notificação enviada quando o status de uma ordem muda. O conteúdo de message segue o mesmo schema retornado por GET /orders/fetchOrder — varia conforme o status:
- Ordens em estados não terminais (ex.:
pending,executed) trazem apenas o bloco base abaixo. - Ordens
closedtrazem o bloco base + campos estendidos (account,orderPoolId,filledStatus,cost,price,info,fee,trades,RFQ). - Ordens
rejectedtrazem o bloco base comerrorMessagepreenchido e sem os campos estendidos.
Exemplo de ordem closed
{
"channel": "watchorders",
"message": {
"id": "string",
"exchange": "string",
"symbol": "string",
"side": "buy",
"type": "market",
"status": "closed",
"errorMessage": "",
"amount": "string",
"amountOriginal": "string",
"remainingAmount": "string",
"quoteAmount": "string",
"quoteAmountOriginal": "string",
"remainingQuoteAmount": "string",
"average": "string",
"createdAt": 1712100000,
"updatedAt": 1712100012,
"executedAt": 1712100012,
"channel": "string",
"rule": "string",
"operationalFees": "string",
"account": "string",
"orderPoolId": "string",
"filledStatus": "filled",
"filled": "string",
"remaining": "string",
"cost": "string",
"price": "string",
"info": "string",
"fee": {
"cost": "string",
"rate": "string",
"cripto": "string",
"tierCaas": {
"currentTierFeeRate": "string",
"currentTierFeeFiat": "string",
"currentTierFeeCripto": "string"
}
},
"trades": [
{
"id": "string",
"takerOrMaker": "string",
"type": "string",
"side": "string",
"price": "string",
"amount": "string",
"cost": "string",
"timestamp": 1712100012,
"fee": {
"cost": "string",
"rate": "string",
"cripto": "string"
}
}
]
}
}
Exemplo de ordem rejected
{
"channel": "watchorders",
"message": {
"id": "string",
"exchange": "string",
"symbol": "string",
"side": "sell",
"type": "market",
"status": "rejected",
"errorMessage": "Insufficient balance",
"amount": "string",
"quoteAmount": "string",
"quoteAmountOriginal": "string",
"remainingQuoteAmount": "string",
"average": "0",
"createdAt": 1712100000,
"updatedAt": 1712100120,
"channel": "string",
"rule": "string",
"operationalFees": "string"
}
}
Campos do message
Campos base (presentes em qualquer status)
| Campo | Tipo | Descrição |
|---|---|---|
id | string | Identificador da ordem |
exchange | string | Exchange utilizada. Em modo liqi-managed retorna "liqi". |
symbol | string | Par de mercado (ex: BTC/BRL) |
side | string | buy ou sell |
type | string | Tipo da ordem (market por padrão) |
status | string | Status atual — ver tabela de status abaixo |
errorMessage | string | Mensagem de erro quando status = "rejected"; vazio nos demais casos |
amount | string | Quantidade de cripto |
quoteAmount | string | Valor em FIAT (R$) |
quoteAmountOriginal | string | Valor em FIAT originalmente solicitado |
remainingQuoteAmount | string | Valor restante em FIAT |
average | string | Preço médio de execução |
createdAt | number | Timestamp Unix de criação |
updatedAt | number | Timestamp Unix da última atualização |
executedAt | number? | Timestamp Unix da execução (quando aplicável) |
channel | string | Canal de origem da ordem |
rule | string | Regra SOR utilizada |
operationalFees | string | Taxas operacionais |
executedExchange | string? | Exchange que de fato executou. Presente quando difere do exchange — em modo liqi-managed é aqui que vem o nome real |
evaluatedTickers | array? | Preço que cada exchange oferecia no instante da cotação, e o motivo do desvio quando houve contingência. Mesmo conteúdo da consulta REST — ver Melhor execução |
O payload deste canal é montado pelo mesmo formatador da consulta fetchOrder: campo que aparece lá aparece aqui, no mesmo formato.
Campos estendidos (apenas em status = "closed")
| Campo | Tipo | Descrição |
|---|---|---|
account | string | ID da conta do cliente |
orderPoolId | string | ID da ordem no pool |
filledStatus | string | Detalhe do preenchimento (ex.: filled, partiallyFilled) |
amountOriginal | string | Quantidade originalmente solicitada |
remainingAmount | string | Quantidade restante em cripto |
filled | string | Quantidade efetivamente preenchida |
remaining | string | Quantidade restante a preencher |
cost | string | Custo total da ordem |
price | string | Preço médio |
info | string | Informação adicional do provedor |
fee | object | Detalhes das taxas (Liqi + tier) |
trades | array | Lista de trades individuais que compuseram a ordem |
RFQ | object? | Detalhes da cotação RFQ (somente em ordens RFQ executadas) |
Status possíveis
| Status | Descrição |
|---|---|
pending | Ordem aberta, em validação ou aguardando execução |
executed | Ordem executada no provedor, aguardando finalização |
closed | Ordem finalizada com sucesso (campos estendidos presentes) |
rejected | Ordem rejeitada (errorMessage preenchido) |
expired | Cotação RFQ que expirou antes de virar ordem |
O canal sempre chega em minúsculas no payload ("channel": "watchorders"), mesmo se você tiver subscrito como watchOrders.
Ordem a limite
O canal cobre a ordem a limite desde agosto de 2026, e publica todas as mudanças de status — não apenas o encerramento.
| Transição | Quando chega |
|---|---|
OPEN | a ordem foi validada e passou a ser observada |
TRIGGERED | o preço alcançou o alvo e a execução foi disparada |
PROCESSING / EXECUTED / closed | o ciclo de execução, igual ao da ordem a mercado |
OPEN (de novo) | re-arm: a execução falhou de forma recuperável e a ordem voltou a observar |
CANCELLING | cancelamento de uma ordem foi aceito (não ocorre no cancelamento em lote) |
CANCELLED | cancelamento concluído — um evento por ordem, inclusive no lote |
EXPIRED | o prazo terminou sem a ordem atingir o alvo |
REJECTED | recusa definitiva (duplicata, saldo, ou falha irrecuperável) |
O message é o mesmo objeto do fetchOrder: além dos campos base desta página, a ordem a limite traz type: "limit", limitPrice, expiresAt, statusGroup e statusReason. Campo novo da ordem a limite passa a viajar aqui automaticamente, sem mudança de contrato.
A entrega é de melhor esforço: uma conexão que caiu não recebe o que perdeu, e não há reenvio. A fonte do estado continua sendo o REST — para reconciliar, use fetchOrder com orderId + status + updatedAt.
Exemplo JavaScript
const token = 'SEU_TOKEN_OPERACIONAL';
const ws = new WebSocket(`wss://websocket-caas-it-sandbox.liqi.app.br/?token=${token}`);
ws.onopen = () => {
ws.send(JSON.stringify({
action: 'subscribe',
channel: 'watchOrders'
}));
};
ws.onmessage = (event) => {
const { channel, message } = JSON.parse(event.data);
if (channel === 'watchorders') {
console.log(`Ordem ${message.id}: ${message.status}`);
console.log(`${message.side} ${message.amount} ${message.symbol} @ ${message.average}`);
}
};