Consignado Público - Consulta de Margem
A consulta de margem pergunta ao ente consignante quais vínculos um CPF tem e quanta margem há em cada um. É o primeiro passo de qualquer operação: uma averbação só é aceita sobre um vínculo que uma consulta já observou.
Esta API está em fase de desenvolvimento, sendo assim, esta página está sujeita a alterações.
A consulta é assíncrona. A criação devolve 202 com a chave da consulta, o resultado chega por webhook e o documento fica disponível na consulta por chave.
Criar uma consulta
entity_level e consignment_entity identificam o ente. Ver Entes Consignantes.
Request
Request Body
{
"employee_document_number": "12345678901",
...
}
Request Body Details
| Campo | Tipo | Descrição | Obrigatório |
|---|---|---|---|
| employee_document_number | string | CPF do servidor, apenas dígitos | Sim |
O restante do corpo depende do perfil de consignação do ente, porque cada plataforma possui um escopo e esquema de autorização próprio para a consulta:
- Perfil 1
Request Body
{
"employee_document_number": "12345678901",
"authorization_term": {
"signature": {
"signer": {
"name": "Nome do Servidor",
"document_number": "12345678901",
"email": "servidor@email.com",
"phone": {
"country_code": "55",
"area_code": "11",
"number": "999999999"
}
},
"authentication_type": "opt_in",
"authenticity": {
"timestamp": "2026-08-26T13:00:00Z",
"ip_address": "200.100.50.25",
"session_id": "0b73fdb9-1b3b-4f09-9cf2-b775a1ce58d2",
"fingerprint": {},
"geolocation": {
"latitude": -23.55,
"longitude": -46.63
}
}
}
}
}
Request Body Details
| Campo | Tipo | Descrição | Obrigatório |
|---|---|---|---|
| authorization_term | object | Termo de autorização: a evidência da anuência do servidor para a consulta | Não |
| authorization_term.signature.signer.name | string | Nome de quem assinou o termo, até 200 caracteres | Sim, se authorization_term |
| authorization_term.signature.signer.document_number | string | CPF de quem assinou. Deve ser o CPF do servidor | Sim, se authorization_term |
| authorization_term.signature.signer.email | string | Email de quem assinou, até 200 caracteres | Não |
| authorization_term.signature.signer.phone | object | Telefone de quem assinou, {country_code, area_code, number}: código do país com 2 ou 3 caracteres, DDD com 2 e número com 8 ou 9 | Não |
| authorization_term.signature.signer.contact_type | string | Canal de contato: sms, email ou whatsapp | Não |
| authorization_term.signature.authentication_type | string | Obrigatoriamente opt_in | Sim, se authorization_term |
| authorization_term.signature.authenticity.timestamp | string | Momento do aceite, em UTC, exatamente no formato AAAA-MM-DDTHH:MM:SSZ (2026-08-26T13:00:00Z), sem milissegundos e sem fuso. Não pode ser posterior ao momento atual | Sim, se authorization_term |
| authorization_term.signature.authenticity.ip_address | string | IP da sessão do servidor, IPv4 ou IPv6 | Sim, se authorization_term |
| authorization_term.signature.authenticity.session_id | string | Identificador da sessão do servidor, de 10 a 50 caracteres | Sim, se authorization_term |
| authorization_term.signature.authenticity.fingerprint | object | Evidências adicionais do aceite, como dispositivo e navegador. Pode ser um objeto vazio | Sim, se authorization_term |
| authorization_term.signature.authenticity.geolocation | object | Localização do aceite, {latitude, longitude} | Não |
A consulta de margem no perfil 1 ocorre a nível de ente, retornando todas as matrículas deste servidor em todos os órgãos do ente.
Essa consulta depende da autorização do servidor no ente. Quando o parceiro já colheu essa autorização, envie-a em authorization_term: a QI Tech registra a anuência no ente antes de consultar. O ente recebe apenas a data do aceite, no horário de São Paulo, e o canal digital; o restante do termo fica com a QI Tech como evidência. Sem authorization_term, a consulta é feita direto, e o próprio ente informa se o servidor a autorizou.
Com authorization_term, a resposta do ente ao registro decide se a consulta segue:
| Resposta do ente ao registro | Resultado |
|---|---|
| Registra a anuência | A consulta segue |
A anuência já estava registrada (ESCC0580) | A consulta segue |
A anuência aguarda a aprovação do próprio servidor (ESCC0579) | A consulta segue |
O ente não aceita anuência registrada pelo consignatário (ESCC0581) | A consulta segue |
| Qualquer outra recusa | A consulta termina em failed, com o motivo da recusa |
Quando a consulta segue, o ente ainda pode responder que o servidor não autorizou, e ela termina em failed com employee_not_authorized. Ver Quando a consulta falha.
Response
Response Body
{
"balance_inquiry_key": "b1b9f0a6-9a3e-4f9b-9d6f-3a5f8c1d2e7b",
"status": "pending",
"created_at": "2026-08-26T13:02:11Z"
}
Response Body Details
| Campo | Tipo | Descrição |
|---|---|---|
| balance_inquiry_key | string | Chave da consulta. É por ela que o resultado é recuperado |
| status | string | Situação da consulta. Enum: Status da consulta |
| created_at | string | Momento da criação da consulta, em UTC |
Erros
| Status | Código | Quando ocorre |
|---|---|---|
| 400 | SCC000003 | employee_document_number não é um CPF válido: dígitos verificadores incorretos, ou um único dígito repetido |
| 400 | SCC000003 | authorization_term.signature.signer.document_number não é um CPF válido |
| 400 | QIT000400 | O corpo não segue o esquema: campo obrigatório ausente, campo não previsto ou formato inválido, como um timestamp com milissegundos. description indica o campo. Também quando timestamp não é uma data existente, como 2026-02-30T10:00:00Z |
| 404 | SCC000202 | O ente da rota não existe |
| 422 | SCC000204 | O parceiro não está configurado para o Consignado Público |
| 422 | SCC000302 | authorization_term.signature.authenticity.timestamp é posterior ao momento atual |
| 422 | SCC000303 | O CPF do assinante não é o CPF do servidor |
Consultar o resultado
Response
Response Body
{
"balance_inquiry_key": "b1b9f0a6-9a3e-4f9b-9d6f-3a5f8c1d2e7b",
"requester_key": "4d1e8c2a-7b3f-4e9a-8c5d-2f6a1b0e9c3d",
"status": "completed",
"observed_at": "2026-08-26T13:02:40Z",
"consignment_entity": {
"code": "39467292",
"enumerator": "sp",
"name": "Governo do Estado de São Paulo"
},
"employee": {
"document_number": "12345678901",
"name": "Nome do Servidor"
},
"authorization_term": {
"signed_at": "2026-08-26T13:00:00Z",
"authentication_type": "opt_in",
"signer": {
"name": "Nome do Servidor",
"document_number": "12345678901"
}
},
"employment_relationships": [
...
]
}
Response Body Details
| Campo | Tipo | Descrição |
|---|---|---|
| balance_inquiry_key | string | Chave da consulta |
| requester_key | string | Chave do parceiro que criou a consulta |
| status | string | Situação da consulta. Enum: Status da consulta |
| reason | object | Motivo da falha. Presente apenas em uma consulta failed. Ver Motivos |
| observed_at | string | Momento em que a QI Tech recebeu a resposta do ente, em UTC. É a idade real do dado. null enquanto a consulta está pending |
| consignment_entity | object | Ente consultado, no formato {code, enumerator, name} |
| employee.document_number | string | CPF consultado |
| employee.name | string | Nome do servidor, como o ente o informa. null enquanto a consulta está pending e quando o ente não reconhece o CPF |
| authorization_term | object | Resumo do termo enviado na criação: signed_at (o timestamp do aceite), authentication_type, e signer (name, document_number). As evidências de autenticidade não são devolvidas. null quando a consulta foi criada sem termo |
| employment_relationships | array | Os vínculos encontrados. Vazio quando a consulta falha |
O conteúdo de employment_relationships é o que muda com o perfil, porque é a plataforma do ente que define como a margem é estruturada:
- Perfil 1
Um item por matrícula, com a margem já consolidada.
Response Body
{
"employment_relationships": [
{
"agency": {
"code": "20065",
"enumerator": "spprev",
"name": "SPPREV"
},
"registration_number": "1234567890123",
"next_payroll_date": "2026-09-05",
"has_inflight_operation": false,
"margin_rule": "largest_appointment",
"margins": [
{
"product": {
"code": 2,
"enumerator": "credit_card",
"name": "Cartão de Crédito"
},
"available_value": 1400.00
}
]
}
]
}
Response Body Details
| Campo | Tipo | Descrição |
|---|---|---|
| employment_relationships[].agency | object | Órgão da matrícula, no formato {code, enumerator, name}. Enum: Órgãos |
| employment_relationships[].registration_number | string | Matrícula, exatamente como o órgão a emite |
| employment_relationships[].next_payroll_date | string | Próxima data de processamento da folha |
| employment_relationships[].has_inflight_operation | boolean | Indica que há operação em andamento sobre a matrícula |
| employment_relationships[].margin_rule | string | Regra usada para consolidar os provimentos: largest_appointment (o maior provimento) ou summed (a soma dos provimentos) |
| employment_relationships[].margins | array | Margem por produto, consolidada no nível da matrícula |
| margins[].product | object | Produto — o "balde" de margem consumido. Enum: Produtos |
| margins[].available_value | number | Margem disponível, em reais, sem nenhuma reserva de segurança aplicada |
Detalhar por provimento
Por padrão o documento vai até o nível da matrícula, com a margem já consolidada pela regra do ente. Esse é o nível em que a averbação acontece e, portanto, o nível que interessa para ofertar.
Query Params
| Campo | Tipo | Descrição |
|---|---|---|
| expand | string | appointments — acrescenta os provimentos de cada matrícula. history — acrescenta os provimentos e, em cada margem, o histórico de margem bruta |
expand recebe um valor: history já inclui os provimentos, então ?expand=history devolve tudo o que ?expand=appointments devolve e mais o histórico. Uma lista separada por vírgula (appointments,history) é recusada com 400 SCC000002.
Com qualquer uma das expansões, cada margem da matrícula ganha appointment_numbers: os provimentos que compõem o valor consolidado — o maior provimento, na regra largest_appointment, ou todos os provimentos somados, na regra summed.
Os valores por provimento existem para conferência. Quando o ente consolida pela regra do maior provimento, somar os provimentos produz uma margem que não existe — e a averbação será recusada. Use sempre o valor consolidado da matrícula.
Response Body (?expand=history)
{
"registration_number": "1234567890123",
"margins": [
{
"product": {
"code": 2,
"enumerator": "credit_card",
"name": "Cartão de Crédito"
},
"available_value": 1400.00,
"appointment_numbers": ["01"]
}
],
"appointments": [
{
"appointment_number": "01",
"relationship_type": {
"code": 16,
"enumerator": "statutory",
"translation": "Estatutário"
},
"margins": [
{
"product": {
"code": 2,
"enumerator": "credit_card",
"name": "Cartão de Crédito"
},
"available_value": 1400.00,
"situation": {
"code": 1,
"enumerator": "available",
"translation": "Margem disponível"
},
"average_gross_value": 1775.25,
"history": [
{ "reference_month": "2026-07", "gross_value": 1800.00 },
{ "reference_month": "2026-06", "gross_value": 1750.00 },
{ "reference_month": "2026-05", "gross_value": 1775.75 }
]
}
]
}
]
}
Response Body Details
| Campo | Tipo | Descrição |
|---|---|---|
| margins[].appointment_numbers | array | Provimentos que compõem a margem consolidada da matrícula |
| appointments[].appointment_number | string | Número do provimento |
| appointments[].relationship_type | object | Tipo de vínculo. Enum: Tipo de vínculo |
| appointments[].margins[].available_value | number | Margem disponível no provimento |
| appointments[].margins[].situation | object | Situação da margem no provimento. Enum: Situação da margem |
| appointments[].margins[].average_gross_value | number | Média da margem bruta no histórico informado. Apenas com expand=history |
| appointments[].margins[].history | array | Margem bruta das competências anteriores que o ente informou, {reference_month, gross_value}. Apenas com expand=history |
Erros
| Status | Código | Quando ocorre |
|---|---|---|
| 400 | SCC000002 | expand traz um valor diferente de appointments ou history, ou uma lista separada por vírgula |
| 404 | SCC000202 | O ente da rota não existe |
| 404 | SCC000301 | A consulta não existe neste ente |
Consulta estática
Os dados retornados como resultado de uma consulta são estáticos: consultar a mesma chave no futuro devolve exatamente o mesmo conteúdo, com o mesmo observed_at, independente de alterações na margem e novas consultas que possam ter ocorrido no meio tempo.
Não existe endpoint que devolva "a margem mais recente consultada" de um CPF. Para dados atualizados, crie e referencie uma nova consulta.
Uma consulta serve de base para uma averbação até o fim do 30º dia depois da data de observed_at, no horário de Brasília. Depois disso, a consulta continua legível, mas não serve mais de base para uma averbação. Ver Pré-requisitos da reserva.
A margem é indicativa
Dentro do prazo de validade, a margem informada ainda assim é indicativa: ela muda sempre que qualquer instituição averba ou desaverba naquele servidor, inclusive entre a consulta e a averbação. Nenhuma política de validade torna uma consulta segura para contratar às cegas.
A margem só é garantida no momento da averbação. A API devolve o valor bruto informado pelo ente, sem descontar nenhuma reserva de segurança — a margem de segurança que o parceiro deduz antes de ofertar é uma regra do parceiro, aplicada sobre o valor que recebe.
A regra de validade que a QI Tech aplica é única e não configurável: a averbação exige que a última consulta completed do próprio parceiro traga o vínculo e ainda esteja válida. Ver Pré-requisitos da reserva.
Quando a consulta falha
Uma consulta termina em failed quando o ente não pôde respondê-la — tipicamente porque o servidor não autorizou a consulta de margem, ou porque o ente não reconhece o CPF. O corpo vem com o mesmo envelope, employment_relationships vazio e o motivo preenchido:
{
"status": "failed",
"reason": {
"code": "LSCC0001",
"enumerator": "employee_not_authorized",
"description": "The employee did not authorize the margin inquiry",
"translation": "O servidor não autorizou a consulta de margem"
},
"employment_relationships": []
}
Os motivos possíveis são definidos pela plataforma do ente. Ver Motivos.
Margem zerada não é falha. Um vínculo sem margem disponível, ou com margem insuficiente, produz uma consulta completed com o valor que o ente informou — o vínculo e os seus dados continuam válidos e utilizáveis.
Testes em sandbox
Em sandbox, os mesmos entes de produção respondem a partir de cenários fixos, escolhidos pelo CPF consultado. Qualquer CPF válido recebe a resposta de sucesso, exceto os CPFs de falha listados abaixo: os que começam com 2. O mesmo CPF recebe sempre a mesma resposta.
POST /public_payroll/state/sp/balance_inquiry
Resposta de sucesso
A consulta termina em completed, com ou sem authorization_term, e traz seis matrículas, todas em um órgão ativo do ente — em São Paulo, spprev:
| Matrícula | Margem |
|---|---|
<CPF>0001 | Disponível: 1000.00 em optional_consignment, 500.00 em credit_card e 500.00 em benefit_card |
<CPF>0003 | Insuficiente: 0.00 nos três produtos |
<CPF>0008, <CPF>0023, <CPF>0024, <CPF>0025 | Disponível, com os mesmos valores de <CPF>0001 |
Cada matrícula leva a um resultado diferente na reserva: ver Testes em sandbox da reserva.
- A matrícula
<CPF>0001tem os provimentos01(statutory) e02(permanent). A margem consolidada é a do provimento01, pela regralargest_appointment, e só ele traz histórico (expand=history). - O nome do servidor é sempre
SERVIDOR SANDBOX, e a próxima data de folha é o dia 5 do mês seguinte.
CPFs de falha
| CPF | Resultado, com ou sem authorization_term |
|---|---|
20000000108 | failed, motivo LSCC0001 (employee_not_authorized): o servidor não autorizou a consulta. Com authorization_term, o ente registra o termo, e a consulta falha mesmo assim |
Qualquer outro CPF que comece com 2, como 20000000299 | failed, motivo ESCC0187 (employee_not_found): o CPF não consta na base do ente. Com authorization_term, o ente já recusa o registro do termo |
A consulta muda de status em poucos segundos, e o webhook é enviado como em produção.