Regras (API)¶
Para: Dev — Conferido em 2026-10-18.
A API deixa você ler as regras vigentes da sua operação e propor uma mudança. Ela nunca altera uma regra:
a proposta fica pendente até outra pessoa aprová-la no painel. Esta página descreve GET /v1/rules, POST /v1/rules/change-requests,
o uso de If-Match e ETag e os erros.
O que é¶
| Rota | Escopo | operationId |
Resposta |
|---|---|---|---|
GET /v1/rules |
read |
obterRegras |
200 com o conjunto de regras vigente (ConjuntoDeRegras) e o cabeçalho ETag |
POST /v1/rules/change-requests |
rules:propose |
pedirMudancaDeRegras |
202 com {"id": "chg_...", "status": "pending_approval"} |
O conjunto de regras define os limites de depósito e saque, o multiplicador do saque automático, o horário do automático e outros
critérios de revisão. Quem aplica as regras é o motor do Dracma, em cada pedido. Os códigos que o motor devolve
(decision.reasons e os 422) estão em Decisão, limites e regras.
Quando usar¶
- Ler quando precisar dos limiares: mínimo e máximo por transação, teto do automático, horário. A página de limites do jogador mostra o que
cabe para um jogador;
GET /v1/rulesmostra a regra da operação inteira. - Propor quando quiser mudar um limite pela API, em vez de pedir ao suporte. Quem tem a chave com o escopo
rules:proposepode propor; a mudança só vigora depois da aprovação no painel.
Os valores de fábrica dos limites não são publicados aqui. Leia os da sua operação com GET /v1/rules.
Como funciona¶
Ler: GET /v1/rules¶
A API devolve o conjunto vigente da operação da chave, no corpo, com o cabeçalho ETag. O motor guarda um conjunto por operação e
a consulta usa a primeira moeda habilitada na operação (veja Ping e moedas). O parâmetro currency não existe nesta rota.
- O
ETagé um valor opaco, entre aspas. Guarde-o exatamente como veio, aspas incluídas: você o envia de volta emIf-Match. - A API não responde
304: toda leitura devolve o corpo inteiro. - Operação sem moeda habilitada ou sem conjunto de regras:
404 not_found. - Motor de regras fora:
503 service_unavailable, repetível.
Campos principais do ConjuntoDeRegras:
| Campo | Tipo | Significado |
|---|---|---|
version |
inteiro | versão do conjunto. Sobe a cada mudança aprovada |
timezone |
texto | fuso IANA da operação (por exemplo America/Sao_Paulo). Define dia, janelas e horário do automático |
currencies |
objeto | uma chave por moeda; o valor traz as regras daquela moeda (tabela abaixo) |
first_withdrawal_manual |
booleano | o primeiro saque pago de cada jogador passa por revisão humana |
pix_key_change_cooldown_hours |
inteiro | carência, em horas, para uma chave PIX nova do jogador |
require_payer_matches_player |
booleano | exige que o pagador do depósito seja o jogador |
auto_hours |
objeto ou null |
{"from": "HH:MM", "to": "HH:MM"}, na hora local da operação, ou null quando não há restrição de horário |
Em currencies.<código>:
| Campo | Tipo | Significado |
|---|---|---|
auto_multiplier |
texto | multiplicador X do saque automático: o automático cobre até X vezes o que o jogador depositou. "0" desliga o automático |
deposit_min, deposit_max |
texto | mínimo e máximo por depósito, na menor unidade |
withdrawal_min, withdrawal_max |
texto | mínimo e máximo por saque, na menor unidade |
auto_max_per_withdrawal |
texto | teto de um saque no automático |
auto_max_per_day |
texto | teto do dia no automático |
dual_approval_above |
texto | acima deste valor, o saque exige duas pessoas na revisão |
max_withdrawals_per_day |
inteiro | quantidade de saques por dia |
O corpo traz mais grupos de configuração do que os listados (janelas, velocidade, destino, pagador, calendário do automático e outros). Trate-os como opacos: leia, mantenha e devolva intactos numa proposta. Campo desconhecido é ignorado na leitura (leitor tolerante).
Reservado no contrato
O grupo bank_transfers do conjunto de regras, com fx e os limites de wire e SWIFT, é aceito e versionado, mas o motor não o aplica: não há
trilho bancário nem câmbio habilitado hoje. Veja Rotas e campos reservados.
Propor: POST /v1/rules/change-requests¶
Uma proposta leva o cabeçalho If-Match e um corpo com dois campos:
| Campo | Obrigatório | Regra |
|---|---|---|
rules |
sim | um objeto com o conjunto de regras proposto |
justification |
sim | texto não vazio, até 1000 caracteres |
Cabeçalhos: If-Match (obrigatório), com o ETag exato do último GET /v1/rules; e Idempotency-Key (todo POST leva).
Fluxo:
- Leia
GET /v1/rulese guarde o corpo e oETag. - Altere uma cópia completa do conjunto. Não mande só o campo que mudou: blocos ausentes na proposta são preenchidos pelo Dracma com o valor de fábrica, o que pode desfazer configuração que você não quis mexer.
- Envie
POST /v1/rules/change-requestscomIf-Matchigual aoETaglido. - A resposta
202traz oidda proposta (chg_seguido de 32 caracteres hexadecimais) estatus: "pending_approval". A regra vigente não mudou. A API nunca altera uma regra. - A aprovação acontece no painel, por uma pessoa da sua equipe com permissão para isso. Mudança que afrouxa limites também espera um prazo antes de vigorar. Veja Regras, listas e emergência.
- Quando a aprovação sai,
GET /v1/rulespassa a devolver o conjunto novo, comversionmaior e outroETag.
A API não tem rota para consultar o estado de uma proposta. Acompanhe pelo painel, ou leia GET /v1/rules e compare version e ETag.
Exemplos¶
GET /v1/rules, resposta 200 (os valores abaixo são ilustrativos, não são valores de fábrica):
HTTP/1.1 200 OK
Content-Type: application/json
ETag: "<etag>"
{
"version": 4,
"timezone": "America/Sao_Paulo",
"currencies": {
"BRL": {
"auto_multiplier": "1",
"deposit_min": "1500",
"deposit_max": "3000000",
"withdrawal_min": "2500",
"withdrawal_max": "3000000",
"auto_max_per_withdrawal": "400000",
"auto_max_per_day": "800000",
"dual_approval_above": "1500000",
"max_withdrawals_per_day": 4
}
},
"first_withdrawal_manual": true,
"pix_key_change_cooldown_hours": 48,
"require_payer_matches_player": true,
"auto_hours": { "from": "08:00", "to": "22:00" }
}
Proposta:
POST /v1/rules/change-requests HTTP/1.1
Host: api.example.test
Content-Type: application/json; charset=utf-8
If-Match: "<etag>"
Idempotency-Key: rules-2026-10-18-0001
Dracma-Key-Id: key_test_01J9EXEMPLO
Dracma-Timestamp: 1790000300
Dracma-Nonce: 0123456789abcdef0123456789abcdef
Dracma-Signature: v1=<assinatura>
{
"rules": { "version": 4, "timezone": "America/Sao_Paulo", "currencies": { "BRL": { "...": "o conjunto completo, com a mudança" } } },
"justification": "Reduzir o teto diário do automático durante a campanha."
}
Resposta 202:
{
"id": "chg_0192a3b40c6d7e8f9a0b1c2d3e4f5a6b",
"status": "pending_approval"
}
Resposta 412 quando o ETag ficou velho:
{
"type": "https://docs.dracma.test/errors/etag_mismatch",
"title": "etag_mismatch",
"status": 412,
"code": "etag_mismatch",
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
"retryable": false
}
Erros e casos de borda¶
| Rota | Situação | Resposta |
|---|---|---|
POST |
If-Match ausente |
400 validation_failed, field: If-Match, reason: required |
POST |
corpo que não é JSON válido, ou tem campo fora de rules e justification |
400, field: body, reason: invalid_json |
POST |
rules ausente ou que não é objeto |
400, field: rules, reason: required |
POST |
justification vazia ou com mais de 1000 caracteres |
400, field: justification, reason: length |
POST |
o motor recusa o conjunto proposto (forma, campo desconhecido ou valor inválido) | 400, field: rules, reason: invalid |
POST |
If-Match diferente do ETag vigente |
412 etag_mismatch |
GET e POST |
operação sem conjunto de regras | 404 not_found |
GET e POST |
motor de regras fora | 503 service_unavailable, repetível |
POST |
chave sem o escopo rules:propose |
403 insufficient_scope |
412não é erro do seu código. Alguém aprovou uma mudança, ou oETagcaducou. ReleiaGET /v1/rules, refaça a mudança sobre o conjunto novo e proponha de novo. Não repita oPOSTcom o mesmoIf-Match.- O
If-Matché comparado como texto, com as aspas. Mande o valor exatamente como oGETdevolveu. - A proposta registra a chave que a enviou (a operação e o autor vêm da credencial, nunca do corpo).
- Os limiares de revisão dependem do conjunto. Depois de propor, não mude o seu código esperando o efeito: ele só existe depois da aprovação.
Veja também¶
- Decisão, limites e regras: o que cada código significa.
- Regras, listas e emergência: aprovação no painel.
- Limites do jogador e saldos: a posição de um jogador.
- Erros