{
  "openapi": "3.1.0",
  "info": {
    "title": "API pública do BetBackoffice",
    "version": "1.1.0",
    "description": "API pública do BetBackoffice para operadoras que constroem o próprio front-end. Uso **servidor a servidor**: o navegador do jogador nunca chama esta API — o servidor do cliente (BFF) guarda os segredos e assina cada requisição.\n\n## Autenticação (HMAC-SHA256)\n\nToda rota (exceto as públicas de metadados) exige três cabeçalhos:\n\n- `X-Operator-Key`: chave da credencial do operador.\n- `X-Timestamp`: epoch em segundos; tolerância de ±5 minutos.\n- `X-Signature`: hex de `HMAC_SHA256(secret, string_canonica)`.\n\n```text\nstring_canonica = METODO + \"\\n\" + CAMINHO_COM_QUERY + \"\\n\" + TIMESTAMP + \"\\n\" + SHA256_HEX(CORPO)\n```\n\n`CAMINHO_COM_QUERY` é o caminho **exatamente como enviado**, incluindo `/api/v1` e a query string. `CORPO` são os bytes enviados (vazio em GET).\n\n## Idempotência\n\nOperações que criam recursos ou movimentam dinheiro exigem `Idempotency-Key` (8–128 caracteres). Repetir a mesma requisição com a mesma chave devolve a resposta original (`Idempotent-Replayed: true`); a mesma chave com corpo diferente retorna `409 IDEMPOTENCY_CONFLICT`. As chaves são lembradas por 24 horas.\n\n## Webhooks\n\nEventos de saída (seção `webhooks` desta especificação) são enviados por `POST` à URL configurada para o seu operador. Cada entrega traz `X-Webhook-Id` (id do evento, use para deduplicar), `X-Webhook-Timestamp` e `X-Webhook-Signature` = hex de `HMAC_SHA256(webhook_secret, TIMESTAMP + \".\" + CORPO_BRUTO)`. Responda com qualquer `2xx`; outras respostas são retentadas com espera exponencial por até 8 tentativas. Entregas são *at-least-once*: podem repetir. Use `POST /webhooks/test` para validar a integração.\n\n## Convenções\n\n- Valores monetários são **strings decimais** com 2 casas (`\"100.00\"`); a moeda é a do jogador.\n- Datas em ISO 8601 UTC.\n- Erros: `{ \"error\": { \"code\", \"message\", \"requestId\", \"details\" } }`. O `code` é estável; a `message` pode mudar.\n- Todas as respostas trazem `X-Request-Id`.\n- Limite de requisições por operador (padrão 600/min); ao exceder, `429` com `Retry-After`."
  },
  "servers": [
    {
      "url": "https://backoffice.betfoguete.bet/api/v1",
      "description": "Servidor único: o ambiente é definido pela sua chave — `bk_live_…` opera em produção; `bk_test_…` opera na marca sandbox, com dados isolados."
    }
  ],
  "tags": [
    {
      "name": "Metadados",
      "description": "Comece por `GET /me`: ele confirma que a assinatura HMAC está correta e mostra a qual operador, marca e ambiente (sandbox ou produção) a sua chave pertence. A especificação e o changelog são públicos."
    },
    {
      "name": "Jogadores",
      "description": "Cadastro e consulta de jogadores da sua marca. Use o `externalId` (o id do jogador no seu sistema) para localizar o jogador sem guardar o id do BetBackoffice. A API não recebe senha: o login é do seu front."
    },
    {
      "name": "Carteira",
      "description": "Saldo e extrato. `available` é o saldo real; `withdrawable` já desconta os saques em aberto."
    },
    {
      "name": "KYC",
      "description": "Verificação de identidade. Você registra o envio do documento; a decisão é da equipe de compliance (em sandbox, use a tag **Sandbox** para simulá-la). Acompanhe pelo webhook `kyc.status_changed`."
    },
    {
      "name": "Depósitos",
      "description": "O meio de pagamento é seu. Crie o depósito (fica `pending`), receba o pagamento no seu PSP e então chame **confirm** para creditar a carteira — ou **fail** se não se concretizar."
    },
    {
      "name": "Saques",
      "description": "Os pedidos entram na fila de análise da equipe. Exige KYC aprovado. O saldo só é debitado no pagamento."
    },
    {
      "name": "Jogos",
      "description": "Catálogo e sessão de jogo. A sessão devolve a `gameUrl` para o navegador do jogador; em sandbox ela é uma sessão de demonstração (saldo fictício)."
    },
    {
      "name": "Webhooks",
      "description": "Eventos de saída assinados (veja a seção *webhooks* desta especificação). Use `POST /webhooks/test` para validar a sua URL e a verificação de assinatura."
    },
    {
      "name": "Sandbox",
      "description": "Atalhos **exclusivos de sandbox** para percorrer o fluxo completo sozinho, simulando as decisões da equipe (KYC e saque). Em produção respondem `403 SANDBOX_ONLY`."
    }
  ],
  "x-tagGroups": [
    {
      "name": "Comece por aqui",
      "tags": [
        "Metadados"
      ]
    },
    {
      "name": "Conta do jogador",
      "tags": [
        "Jogadores",
        "KYC",
        "Carteira"
      ]
    },
    {
      "name": "Dinheiro",
      "tags": [
        "Depósitos",
        "Saques"
      ]
    },
    {
      "name": "Jogo",
      "tags": [
        "Jogos"
      ]
    },
    {
      "name": "Eventos",
      "tags": [
        "Webhooks"
      ]
    },
    {
      "name": "Sandbox",
      "tags": [
        "Sandbox"
      ]
    }
  ],
  "security": [
    {
      "OperatorKey": [],
      "Timestamp": [],
      "Signature": []
    }
  ],
  "paths": {
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApi",
        "summary": "Especificação OpenAPI",
        "description": "Documento OpenAPI 3.1 desta versão da API. Público, sem autenticação.",
        "tags": [
          "Metadados"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {}
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "curl \"https://backoffice.betfoguete.bet/api/v1/openapi.json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "const res = await fetch(\"https://backoffice.betfoguete.bet/api/v1/openapi.json\");\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import requests\n\nres = requests.get(\"https://backoffice.betfoguete.bet/api/v1/openapi.json\")\nprint(res.status_code, res.text)"
          }
        ]
      }
    },
    "/changelog": {
      "get": {
        "operationId": "getChangelog",
        "summary": "Changelog da API",
        "description": "Histórico de mudanças em Markdown. Público, sem autenticação.",
        "tags": [
          "Metadados"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "text/markdown": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "curl \"https://backoffice.betfoguete.bet/api/v1/changelog\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "const res = await fetch(\"https://backoffice.betfoguete.bet/api/v1/changelog\");\nconsole.log(res.status, await res.text());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import requests\n\nres = requests.get(\"https://backoffice.betfoguete.bet/api/v1/changelog\")\nprint(res.status_code, res.text)"
          }
        ]
      }
    },
    "/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Identidade da credencial",
        "description": "Devolve o operador e a marca associados à credencial usada. Serve para validar a assinatura HMAC na integração.",
        "tags": [
          "Metadados"
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "operator": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "environment": {
                          "type": "string",
                          "enum": [
                            "sandbox",
                            "production"
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "environment"
                      ],
                      "additionalProperties": false
                    },
                    "brand": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "currency": {
                          "type": "string"
                        },
                        "isSandbox": {
                          "description": "Marca de testes: dados isolados da produção",
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "currency",
                        "isSandbox"
                      ],
                      "additionalProperties": false
                    },
                    "apiVersion": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "operator",
                    "brand",
                    "apiVersion"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "operator": {
                    "id": "OPR-2c8d51e4-7a03-4b9f-9e16-5d4a1b8c3f70",
                    "name": "Cliente Exemplo",
                    "environment": "sandbox"
                  },
                  "brand": {
                    "id": "br-sandbox",
                    "name": "Sandbox (testes de integração)",
                    "currency": "BRL",
                    "isSandbox": true
                  },
                  "apiVersion": "1.1.0"
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/me'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'GET\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X GET \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/me\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"GET\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"GET\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/me\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"GET\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n}\nres = requests.request(\"GET\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/postman.json": {
      "get": {
        "operationId": "getPostmanCollection",
        "summary": "Coleção Postman",
        "description": "Coleção Postman v2.1 com todas as operações, corpos de exemplo e um script de pré-requisição que assina cada chamada com HMAC. Importe no Postman, defina `operatorKey` e `operatorSecret` (chaves de sandbox) e envie. Público, sem autenticação.",
        "tags": [
          "Metadados"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {}
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "curl \"https://backoffice.betfoguete.bet/api/v1/postman.json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "const res = await fetch(\"https://backoffice.betfoguete.bet/api/v1/postman.json\");\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import requests\n\nres = requests.get(\"https://backoffice.betfoguete.bet/api/v1/postman.json\")\nprint(res.status_code, res.text)"
          }
        ]
      }
    },
    "/signing-snippets.json": {
      "get": {
        "operationId": "getSigningSnippets",
        "summary": "Snippets de assinatura",
        "description": "Código para assinar requisições e verificar webhooks em Node.js, Python, PHP, Go, Java, C# e curl/openssl. Público, sem autenticação.",
        "tags": [
          "Metadados"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {}
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "curl \"https://backoffice.betfoguete.bet/api/v1/signing-snippets.json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "const res = await fetch(\"https://backoffice.betfoguete.bet/api/v1/signing-snippets.json\");\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import requests\n\nres = requests.get(\"https://backoffice.betfoguete.bet/api/v1/signing-snippets.json\")\nprint(res.status_code, res.text)"
          }
        ]
      }
    },
    "/test-vectors.json": {
      "get": {
        "operationId": "getTestVectors",
        "summary": "Vetores de teste da assinatura",
        "description": "Entradas e assinaturas esperadas (requisição e webhook) para você conferir a sua implementação. Público, sem autenticação.",
        "tags": [
          "Metadados"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {}
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "curl \"https://backoffice.betfoguete.bet/api/v1/test-vectors.json\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "const res = await fetch(\"https://backoffice.betfoguete.bet/api/v1/test-vectors.json\");\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import requests\n\nres = requests.get(\"https://backoffice.betfoguete.bet/api/v1/test-vectors.json\")\nprint(res.status_code, res.text)"
          }
        ]
      }
    },
    "/docs": {
      "get": {
        "operationId": "getDocsPage",
        "summary": "Página de documentação",
        "description": "Página HTML com a referência interativa, primeiros passos, testador assinado (somente sandbox) e downloads. Pública, sem autenticação.",
        "tags": [
          "Metadados"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "curl \"https://backoffice.betfoguete.bet/api/v1/docs\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "const res = await fetch(\"https://backoffice.betfoguete.bet/api/v1/docs\");\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import requests\n\nres = requests.get(\"https://backoffice.betfoguete.bet/api/v1/docs\")\nprint(res.status_code, res.text)"
          }
        ]
      }
    },
    "/players": {
      "post": {
        "operationId": "createPlayer",
        "summary": "Cadastrar jogador",
        "description": "Cria a conta do jogador na marca do operador, com KYC `nao_iniciado`. O login do jogador é responsabilidade do seu front-end: a API não recebe senha.",
        "tags": [
          "Jogadores"
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Chave única por intenção (8–128 caracteres). Reenvie a mesma em retentativas.",
            "example": "6f1e2d3c-4b5a-4978-8a9b-0c1d2e3f4a5b",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "externalId": {
                    "description": "Identificador do jogador no seu sistema; único por marca",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  },
                  "name": {
                    "type": "string",
                    "minLength": 2,
                    "maxLength": 200
                  },
                  "email": {
                    "type": "string",
                    "maxLength": 254,
                    "format": "email",
                    "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  },
                  "cpf": {
                    "description": "CPF válido, com ou sem pontuação",
                    "type": "string"
                  },
                  "phone": {
                    "type": "string",
                    "pattern": "^\\+?\\d{10,15}$"
                  },
                  "birthDate": {
                    "description": "YYYY-MM-DD; maior de 18 anos",
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  }
                },
                "required": [
                  "externalId",
                  "name",
                  "email",
                  "cpf",
                  "birthDate"
                ]
              },
              "example": {
                "externalId": "jogador-123",
                "name": "Ana Souza",
                "email": "ana.souza@exemplo.com",
                "cpf": "52998224725",
                "phone": "11999998888",
                "birthDate": "1990-05-20"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Identificador do jogador no BetBackoffice",
                      "type": "string"
                    },
                    "externalId": {
                      "description": "Identificador do jogador no sistema do operador",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "name": {
                      "type": "string"
                    },
                    "email": {
                      "type": "string"
                    },
                    "cpf": {
                      "description": "Somente dígitos",
                      "type": "string"
                    },
                    "phone": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "birthDate": {
                      "description": "YYYY-MM-DD",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "ativo",
                        "suspenso",
                        "bloqueado",
                        "autoexcluido",
                        "encerrado",
                        "restrito"
                      ]
                    },
                    "kycStatus": {
                      "type": "string",
                      "enum": [
                        "nao_iniciado",
                        "pendente",
                        "em_analise",
                        "documento_solicitado",
                        "aprovado",
                        "reprovado",
                        "expirado"
                      ]
                    },
                    "currency": {
                      "description": "Moeda da conta (ISO 4217)",
                      "type": "string"
                    },
                    "createdAt": {
                      "description": "ISO 8601 UTC",
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "externalId",
                    "name",
                    "email",
                    "cpf",
                    "phone",
                    "birthDate",
                    "status",
                    "kycStatus",
                    "currency",
                    "createdAt"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "id": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "externalId": "jogador-123",
                  "name": "Ana Souza",
                  "email": "ana.souza@exemplo.com",
                  "cpf": "52998224725",
                  "phone": "11999998888",
                  "birthDate": "1990-05-20",
                  "status": "ativo",
                  "kycStatus": "nao_iniciado",
                  "currency": "BRL",
                  "createdAt": "2026-09-25T14:03:11.482Z"
                }
              }
            }
          },
          "400": {
            "description": "Erro: `IDEMPOTENCY_KEY_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_KEY_REQUIRED",
                    "message": "O cabeçalho Idempotency-Key é obrigatório nesta operação",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erro: `IDEMPOTENCY_CONFLICT`, `IDEMPOTENCY_IN_PROGRESS`, `PLAYER_ALREADY_EXISTS`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_CONFLICT",
                    "message": "Idempotency-Key já usada com uma requisição diferente",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY='{\"externalId\":\"jogador-123\",\"name\":\"Ana Souza\",\"email\":\"ana.souza@exemplo.com\",\"cpf\":\"52998224725\",\"phone\":\"11999998888\",\"birthDate\":\"1990-05-20\"}'\nPATH_Q='/api/v1/players'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'POST\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X POST \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"$BODY\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/players\";\nconst body = JSON.stringify({\n  \"externalId\": \"jogador-123\",\n  \"name\": \"Ana Souza\",\n  \"email\": \"ana.souza@exemplo.com\",\n  \"cpf\": \"52998224725\",\n  \"phone\": \"11999998888\",\n  \"birthDate\": \"1990-05-20\"\n});\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"POST\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": randomUUID(),\n  },\n  body,\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/players\"\nbody = json.dumps({\n    \"externalId\": \"jogador-123\",\n    \"name\": \"Ana Souza\",\n    \"email\": \"ana.souza@exemplo.com\",\n    \"cpf\": \"52998224725\",\n    \"phone\": \"11999998888\",\n    \"birthDate\": \"1990-05-20\"\n}, separators=(\",\", \":\"))\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"POST\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": str(uuid.uuid4()),\n}\nres = requests.request(\"POST\", BASE_URL + path, headers=headers, data=body)\nprint(res.status_code, res.json())"
          }
        ]
      },
      "get": {
        "operationId": "listPlayers",
        "summary": "Buscar jogador por externalId",
        "description": "Devolve o jogador da sua marca com o `externalId` informado (lista vazia se não existir).",
        "tags": [
          "Jogadores"
        ],
        "parameters": [
          {
            "name": "externalId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "example": "jogador-123"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Identificador do jogador no BetBackoffice",
                            "type": "string"
                          },
                          "externalId": {
                            "description": "Identificador do jogador no sistema do operador",
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "name": {
                            "type": "string"
                          },
                          "email": {
                            "type": "string"
                          },
                          "cpf": {
                            "description": "Somente dígitos",
                            "type": "string"
                          },
                          "phone": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "birthDate": {
                            "description": "YYYY-MM-DD",
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "ativo",
                              "suspenso",
                              "bloqueado",
                              "autoexcluido",
                              "encerrado",
                              "restrito"
                            ]
                          },
                          "kycStatus": {
                            "type": "string",
                            "enum": [
                              "nao_iniciado",
                              "pendente",
                              "em_analise",
                              "documento_solicitado",
                              "aprovado",
                              "reprovado",
                              "expirado"
                            ]
                          },
                          "currency": {
                            "description": "Moeda da conta (ISO 4217)",
                            "type": "string"
                          },
                          "createdAt": {
                            "description": "ISO 8601 UTC",
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "externalId",
                          "name",
                          "email",
                          "cpf",
                          "phone",
                          "birthDate",
                          "status",
                          "kycStatus",
                          "currency",
                          "createdAt"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                      "externalId": "jogador-123",
                      "name": "Ana Souza",
                      "email": "ana.souza@exemplo.com",
                      "cpf": "52998224725",
                      "phone": "11999998888",
                      "birthDate": "1990-05-20",
                      "status": "ativo",
                      "kycStatus": "nao_iniciado",
                      "currency": "BRL",
                      "createdAt": "2026-09-25T14:03:11.482Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/players?externalId=jogador-123'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'GET\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X GET \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/players?externalId=jogador-123\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"GET\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"GET\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/players?externalId=jogador-123\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"GET\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n}\nres = requests.request(\"GET\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/players/{playerId}": {
      "get": {
        "operationId": "getPlayer",
        "summary": "Consultar jogador",
        "tags": [
          "Jogadores"
        ],
        "parameters": [
          {
            "name": "playerId",
            "in": "path",
            "required": true,
            "schema": {
              "description": "Identificador do jogador no BetBackoffice",
              "type": "string",
              "minLength": 1
            },
            "description": "Identificador do jogador no BetBackoffice",
            "example": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "description": "Identificador do jogador no BetBackoffice",
                      "type": "string"
                    },
                    "externalId": {
                      "description": "Identificador do jogador no sistema do operador",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "name": {
                      "type": "string"
                    },
                    "email": {
                      "type": "string"
                    },
                    "cpf": {
                      "description": "Somente dígitos",
                      "type": "string"
                    },
                    "phone": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "birthDate": {
                      "description": "YYYY-MM-DD",
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "ativo",
                        "suspenso",
                        "bloqueado",
                        "autoexcluido",
                        "encerrado",
                        "restrito"
                      ]
                    },
                    "kycStatus": {
                      "type": "string",
                      "enum": [
                        "nao_iniciado",
                        "pendente",
                        "em_analise",
                        "documento_solicitado",
                        "aprovado",
                        "reprovado",
                        "expirado"
                      ]
                    },
                    "currency": {
                      "description": "Moeda da conta (ISO 4217)",
                      "type": "string"
                    },
                    "createdAt": {
                      "description": "ISO 8601 UTC",
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "externalId",
                    "name",
                    "email",
                    "cpf",
                    "phone",
                    "birthDate",
                    "status",
                    "kycStatus",
                    "currency",
                    "createdAt"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "id": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "externalId": "jogador-123",
                  "name": "Ana Souza",
                  "email": "ana.souza@exemplo.com",
                  "cpf": "52998224725",
                  "phone": "11999998888",
                  "birthDate": "1990-05-20",
                  "status": "ativo",
                  "kycStatus": "nao_iniciado",
                  "currency": "BRL",
                  "createdAt": "2026-09-25T14:03:11.482Z"
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `PLAYER_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PLAYER_NOT_FOUND",
                    "message": "Jogador não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'GET\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X GET \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"GET\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"GET\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"GET\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n}\nres = requests.request(\"GET\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/players/{playerId}/wallet": {
      "get": {
        "operationId": "getWallet",
        "summary": "Saldo do jogador",
        "tags": [
          "Carteira"
        ],
        "parameters": [
          {
            "name": "playerId",
            "in": "path",
            "required": true,
            "schema": {
              "description": "Identificador do jogador no BetBackoffice",
              "type": "string",
              "minLength": 1
            },
            "description": "Identificador do jogador no BetBackoffice",
            "example": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "playerId": {
                      "type": "string"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "available": {
                      "description": "Saldo real disponível",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "withdrawable": {
                      "description": "Disponível para saque: saldo real menos saques em aberto",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "bonus": {
                      "description": "Saldo de bônus",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "locked": {
                      "description": "Saldo bloqueado",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "pending": {
                      "description": "Saldo pendente",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    }
                  },
                  "required": [
                    "playerId",
                    "currency",
                    "available",
                    "withdrawable",
                    "bonus",
                    "locked",
                    "pending"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "currency": "BRL",
                  "available": "150.00",
                  "withdrawable": "100.00",
                  "bonus": "0.00",
                  "locked": "0.00",
                  "pending": "0.00"
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `PLAYER_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PLAYER_NOT_FOUND",
                    "message": "Jogador não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/wallet'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'GET\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X GET \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/wallet\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"GET\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"GET\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/wallet\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"GET\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n}\nres = requests.request(\"GET\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/players/{playerId}/transactions": {
      "get": {
        "operationId": "listTransactions",
        "summary": "Extrato do jogador",
        "description": "Lançamentos da carteira, do mais recente ao mais antigo. Paginação por cursor: envie `nextCursor` como `cursor` para a próxima página; `nextCursor` nulo indica o fim.",
        "tags": [
          "Carteira"
        ],
        "parameters": [
          {
            "name": "playerId",
            "in": "path",
            "required": true,
            "schema": {
              "description": "Identificador do jogador no BetBackoffice",
              "type": "string",
              "minLength": 1
            },
            "description": "Identificador do jogador no BetBackoffice",
            "example": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34"
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 50,
              "type": "integer",
              "minimum": 1,
              "maximum": 200
            },
            "example": "20"
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 512
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "type": {
                            "description": "DEPOSIT, WITHDRAWAL, BET, WIN, BONUS_CREDIT, BONUS_DEBIT, REFUND, REVERSAL, ADJUSTMENT...",
                            "type": "string"
                          },
                          "wallet": {
                            "type": "string",
                            "enum": [
                              "REAL",
                              "BONUS",
                              "LOCKED",
                              "PENDING"
                            ]
                          },
                          "amount": {
                            "description": "Assinado: positivo credita, negativo debita",
                            "type": "string",
                            "pattern": "^-?\\d+\\.\\d{2}$"
                          },
                          "balanceAfter": {
                            "description": "Valor decimal em string com 2 casas, ex.: \"100.00\"",
                            "type": "string",
                            "pattern": "^-?\\d+\\.\\d{2}$"
                          },
                          "currency": {
                            "type": "string"
                          },
                          "reference": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string"
                                  },
                                  "id": {
                                    "anyOf": [
                                      {
                                        "type": "string"
                                      },
                                      {
                                        "type": "null"
                                      }
                                    ]
                                  }
                                },
                                "required": [
                                  "type",
                                  "id"
                                ],
                                "additionalProperties": false
                              },
                              {
                                "type": "null"
                              }
                            ]
                          },
                          "createdAt": {
                            "description": "ISO 8601 UTC",
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "type",
                          "wallet",
                          "amount",
                          "balanceAfter",
                          "currency",
                          "reference",
                          "createdAt"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "nextCursor": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "data",
                    "nextCursor"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "LDG-0b7a4d92-3e15-4c68-9f2a-6d1e8b5c7a30",
                      "type": "DEPOSIT",
                      "wallet": "REAL",
                      "amount": "150.00",
                      "balanceAfter": "150.00",
                      "currency": "BRL",
                      "reference": {
                        "type": "deposit",
                        "id": "DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58"
                      },
                      "createdAt": "2026-09-25T14:09:30.004Z"
                    }
                  ],
                  "nextCursor": null
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `PLAYER_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PLAYER_NOT_FOUND",
                    "message": "Jogador não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/transactions?limit=20'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'GET\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X GET \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/transactions?limit=20\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"GET\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"GET\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/transactions?limit=20\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"GET\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n}\nres = requests.request(\"GET\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/players/{playerId}/kyc": {
      "get": {
        "operationId": "getKyc",
        "summary": "Situação do KYC",
        "description": "Status da verificação de identidade e caso mais recente. A decisão (aprovar/reprovar) é feita pela equipe de compliance no backoffice.",
        "tags": [
          "KYC"
        ],
        "parameters": [
          {
            "name": "playerId",
            "in": "path",
            "required": true,
            "schema": {
              "description": "Identificador do jogador no BetBackoffice",
              "type": "string",
              "minLength": 1
            },
            "description": "Identificador do jogador no BetBackoffice",
            "example": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "description": "Situação atual da verificação do jogador",
                      "type": "string",
                      "enum": [
                        "nao_iniciado",
                        "pendente",
                        "em_analise",
                        "documento_solicitado",
                        "aprovado",
                        "reprovado",
                        "expirado"
                      ]
                    },
                    "case": {
                      "description": "Caso de KYC mais recente, se houver",
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "documentType": {
                              "type": "string",
                              "enum": [
                                "RG",
                                "CNH",
                                "Passaporte",
                                "Comprovante de residência"
                              ]
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "nao_iniciado",
                                "pendente",
                                "em_analise",
                                "documento_solicitado",
                                "aprovado",
                                "reprovado",
                                "expirado"
                              ]
                            },
                            "submittedAt": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "documentType",
                            "status",
                            "submittedAt"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "status",
                    "case"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "status": "em_analise",
                  "case": {
                    "id": "KYC-9e1f5a3c-6b24-4d78-a0c5-3f8b2d7e1a64",
                    "documentType": "RG",
                    "status": "em_analise",
                    "submittedAt": "2026-09-25T14:05:40.120Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `PLAYER_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PLAYER_NOT_FOUND",
                    "message": "Jogador não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/kyc'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'GET\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X GET \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/kyc\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"GET\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"GET\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/kyc\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"GET\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n}\nres = requests.request(\"GET\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/players/{playerId}/kyc/submissions": {
      "post": {
        "operationId": "submitKycDocument",
        "summary": "Registrar envio de documento",
        "description": "Registra que o jogador enviou um documento e coloca o KYC `em_analise`. Nesta versão a API **não recebe o arquivo**: guarde-o no seu sistema e informe uma `reference` opaca para a equipe de compliance localizá-lo.",
        "tags": [
          "KYC"
        ],
        "parameters": [
          {
            "name": "playerId",
            "in": "path",
            "required": true,
            "schema": {
              "description": "Identificador do jogador no BetBackoffice",
              "type": "string",
              "minLength": 1
            },
            "description": "Identificador do jogador no BetBackoffice",
            "example": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Chave única por intenção (8–128 caracteres). Reenvie a mesma em retentativas.",
            "example": "6f1e2d3c-4b5a-4978-8a9b-0c1d2e3f4a5b",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "documentType": {
                    "type": "string",
                    "enum": [
                      "RG",
                      "CNH",
                      "Passaporte",
                      "Comprovante de residência"
                    ]
                  },
                  "reference": {
                    "description": "Referência do documento no seu sistema",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  }
                },
                "required": [
                  "documentType"
                ]
              },
              "example": {
                "documentType": "RG",
                "reference": "doc-ana-souza-001"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "description": "Situação atual da verificação do jogador",
                      "type": "string",
                      "enum": [
                        "nao_iniciado",
                        "pendente",
                        "em_analise",
                        "documento_solicitado",
                        "aprovado",
                        "reprovado",
                        "expirado"
                      ]
                    },
                    "case": {
                      "description": "Caso de KYC mais recente, se houver",
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "documentType": {
                              "type": "string",
                              "enum": [
                                "RG",
                                "CNH",
                                "Passaporte",
                                "Comprovante de residência"
                              ]
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "nao_iniciado",
                                "pendente",
                                "em_analise",
                                "documento_solicitado",
                                "aprovado",
                                "reprovado",
                                "expirado"
                              ]
                            },
                            "submittedAt": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "documentType",
                            "status",
                            "submittedAt"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "status",
                    "case"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "status": "em_analise",
                  "case": {
                    "id": "KYC-9e1f5a3c-6b24-4d78-a0c5-3f8b2d7e1a64",
                    "documentType": "RG",
                    "status": "em_analise",
                    "submittedAt": "2026-09-25T14:05:40.120Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Erro: `IDEMPOTENCY_KEY_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_KEY_REQUIRED",
                    "message": "O cabeçalho Idempotency-Key é obrigatório nesta operação",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `PLAYER_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PLAYER_NOT_FOUND",
                    "message": "Jogador não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erro: `IDEMPOTENCY_CONFLICT`, `IDEMPOTENCY_IN_PROGRESS`, `KYC_ALREADY_APPROVED`, `PLAYER_NOT_ACTIVE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_CONFLICT",
                    "message": "Idempotency-Key já usada com uma requisição diferente",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY='{\"documentType\":\"RG\",\"reference\":\"doc-ana-souza-001\"}'\nPATH_Q='/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/kyc/submissions'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'POST\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X POST \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"$BODY\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/kyc/submissions\";\nconst body = JSON.stringify({\n  \"documentType\": \"RG\",\n  \"reference\": \"doc-ana-souza-001\"\n});\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"POST\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": randomUUID(),\n  },\n  body,\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/kyc/submissions\"\nbody = json.dumps({\n    \"documentType\": \"RG\",\n    \"reference\": \"doc-ana-souza-001\"\n}, separators=(\",\", \":\"))\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"POST\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": str(uuid.uuid4()),\n}\nres = requests.request(\"POST\", BASE_URL + path, headers=headers, data=body)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/players/{playerId}/deposits": {
      "post": {
        "operationId": "createDeposit",
        "summary": "Criar depósito",
        "description": "Registra a intenção de depósito como `pending`. O meio de pagamento é seu: depois de receber o pagamento, chame `POST /deposits/{depositId}/confirm` para creditar a carteira (ou `/fail` se não se concretizar). Respeita autoexclusão e o limite diário de depósito do jogador.",
        "tags": [
          "Depósitos"
        ],
        "parameters": [
          {
            "name": "playerId",
            "in": "path",
            "required": true,
            "schema": {
              "description": "Identificador do jogador no BetBackoffice",
              "type": "string",
              "minLength": 1
            },
            "description": "Identificador do jogador no BetBackoffice",
            "example": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Chave única por intenção (8–128 caracteres). Reenvie a mesma em retentativas.",
            "example": "6f1e2d3c-4b5a-4978-8a9b-0c1d2e3f4a5b",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "description": "Valor decimal positivo em string com até 2 casas, ex.: \"100.00\"",
                    "type": "string"
                  },
                  "currency": {
                    "description": "Deve ser a moeda do jogador",
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 3
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "PIX",
                      "TED",
                      "Cartão",
                      "Carteira digital"
                    ]
                  },
                  "externalReference": {
                    "description": "Identificador do pagamento no seu PSP; único por operador",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 128
                  }
                },
                "required": [
                  "amount",
                  "currency",
                  "method"
                ]
              },
              "example": {
                "amount": "150.00",
                "currency": "BRL",
                "method": "PIX",
                "externalReference": "psp-2026-000123"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "playerId": {
                      "type": "string"
                    },
                    "amount": {
                      "description": "Valor decimal em string com 2 casas, ex.: \"100.00\"",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "method": {
                      "type": "string",
                      "enum": [
                        "PIX",
                        "TED",
                        "Cartão",
                        "Carteira digital"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "confirmed",
                        "failed",
                        "expired"
                      ]
                    },
                    "externalReference": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "failureReason": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "type": "string"
                    },
                    "confirmedAt": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "playerId",
                    "amount",
                    "currency",
                    "method",
                    "status",
                    "externalReference",
                    "failureReason",
                    "createdAt",
                    "confirmedAt"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "id": "DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58",
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "amount": "150.00",
                  "currency": "BRL",
                  "method": "PIX",
                  "status": "pending",
                  "externalReference": "psp-2026-000123",
                  "failureReason": null,
                  "createdAt": "2026-09-25T14:08:02.771Z",
                  "confirmedAt": null
                }
              }
            }
          },
          "400": {
            "description": "Erro: `IDEMPOTENCY_KEY_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_KEY_REQUIRED",
                    "message": "O cabeçalho Idempotency-Key é obrigatório nesta operação",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `PLAYER_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PLAYER_NOT_FOUND",
                    "message": "Jogador não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erro: `IDEMPOTENCY_CONFLICT`, `IDEMPOTENCY_IN_PROGRESS`, `PLAYER_NOT_ACTIVE`, `RG_BLOCKED`, `DEPOSIT_ALREADY_EXISTS`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_CONFLICT",
                    "message": "Idempotency-Key já usada com uma requisição diferente",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`, `CURRENCY_MISMATCH`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY='{\"amount\":\"150.00\",\"currency\":\"BRL\",\"method\":\"PIX\",\"externalReference\":\"psp-2026-000123\"}'\nPATH_Q='/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/deposits'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'POST\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X POST \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"$BODY\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/deposits\";\nconst body = JSON.stringify({\n  \"amount\": \"150.00\",\n  \"currency\": \"BRL\",\n  \"method\": \"PIX\",\n  \"externalReference\": \"psp-2026-000123\"\n});\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"POST\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": randomUUID(),\n  },\n  body,\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/deposits\"\nbody = json.dumps({\n    \"amount\": \"150.00\",\n    \"currency\": \"BRL\",\n    \"method\": \"PIX\",\n    \"externalReference\": \"psp-2026-000123\"\n}, separators=(\",\", \":\"))\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"POST\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": str(uuid.uuid4()),\n}\nres = requests.request(\"POST\", BASE_URL + path, headers=headers, data=body)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/deposits/{depositId}": {
      "get": {
        "operationId": "getDeposit",
        "summary": "Consultar depósito",
        "tags": [
          "Depósitos"
        ],
        "parameters": [
          {
            "name": "depositId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "playerId": {
                      "type": "string"
                    },
                    "amount": {
                      "description": "Valor decimal em string com 2 casas, ex.: \"100.00\"",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "method": {
                      "type": "string",
                      "enum": [
                        "PIX",
                        "TED",
                        "Cartão",
                        "Carteira digital"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "confirmed",
                        "failed",
                        "expired"
                      ]
                    },
                    "externalReference": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "failureReason": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "type": "string"
                    },
                    "confirmedAt": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "playerId",
                    "amount",
                    "currency",
                    "method",
                    "status",
                    "externalReference",
                    "failureReason",
                    "createdAt",
                    "confirmedAt"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "id": "DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58",
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "amount": "150.00",
                  "currency": "BRL",
                  "method": "PIX",
                  "status": "pending",
                  "externalReference": "psp-2026-000123",
                  "failureReason": null,
                  "createdAt": "2026-09-25T14:08:02.771Z",
                  "confirmedAt": null
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `DEPOSIT_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "DEPOSIT_NOT_FOUND",
                    "message": "Depósito não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/deposits/DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'GET\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X GET \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/deposits/DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"GET\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"GET\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/deposits/DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"GET\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n}\nres = requests.request(\"GET\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/deposits/{depositId}/confirm": {
      "post": {
        "operationId": "confirmDeposit",
        "summary": "Confirmar depósito",
        "description": "Confirma que o pagamento foi recebido e credita o valor na carteira real do jogador, uma única vez.",
        "tags": [
          "Depósitos"
        ],
        "parameters": [
          {
            "name": "depositId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Chave única por intenção (8–128 caracteres). Reenvie a mesma em retentativas.",
            "example": "6f1e2d3c-4b5a-4978-8a9b-0c1d2e3f4a5b",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "playerId": {
                      "type": "string"
                    },
                    "amount": {
                      "description": "Valor decimal em string com 2 casas, ex.: \"100.00\"",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "method": {
                      "type": "string",
                      "enum": [
                        "PIX",
                        "TED",
                        "Cartão",
                        "Carteira digital"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "confirmed",
                        "failed",
                        "expired"
                      ]
                    },
                    "externalReference": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "failureReason": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "type": "string"
                    },
                    "confirmedAt": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "playerId",
                    "amount",
                    "currency",
                    "method",
                    "status",
                    "externalReference",
                    "failureReason",
                    "createdAt",
                    "confirmedAt"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "id": "DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58",
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "amount": "150.00",
                  "currency": "BRL",
                  "method": "PIX",
                  "status": "confirmed",
                  "externalReference": "psp-2026-000123",
                  "failureReason": null,
                  "createdAt": "2026-09-25T14:08:02.771Z",
                  "confirmedAt": "2026-09-25T14:09:30.004Z"
                }
              }
            }
          },
          "400": {
            "description": "Erro: `IDEMPOTENCY_KEY_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_KEY_REQUIRED",
                    "message": "O cabeçalho Idempotency-Key é obrigatório nesta operação",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `DEPOSIT_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "DEPOSIT_NOT_FOUND",
                    "message": "Depósito não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erro: `IDEMPOTENCY_CONFLICT`, `IDEMPOTENCY_IN_PROGRESS`, `DEPOSIT_NOT_PENDING`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_CONFLICT",
                    "message": "Idempotency-Key já usada com uma requisição diferente",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/deposits/DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58/confirm'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'POST\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X POST \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\" \\\n  -H \"Idempotency-Key: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/deposits/DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58/confirm\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"POST\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": randomUUID(),\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/deposits/DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58/confirm\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"POST\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": str(uuid.uuid4()),\n}\nres = requests.request(\"POST\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/deposits/{depositId}/fail": {
      "post": {
        "operationId": "failDeposit",
        "summary": "Marcar depósito como não concretizado",
        "tags": [
          "Depósitos"
        ],
        "parameters": [
          {
            "name": "depositId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Chave única por intenção (8–128 caracteres). Reenvie a mesma em retentativas.",
            "example": "6f1e2d3c-4b5a-4978-8a9b-0c1d2e3f4a5b",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  }
                }
              },
              "example": {
                "reason": "pagamento expirou no PSP"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "playerId": {
                      "type": "string"
                    },
                    "amount": {
                      "description": "Valor decimal em string com 2 casas, ex.: \"100.00\"",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "method": {
                      "type": "string",
                      "enum": [
                        "PIX",
                        "TED",
                        "Cartão",
                        "Carteira digital"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "confirmed",
                        "failed",
                        "expired"
                      ]
                    },
                    "externalReference": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "failureReason": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "createdAt": {
                      "type": "string"
                    },
                    "confirmedAt": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "id",
                    "playerId",
                    "amount",
                    "currency",
                    "method",
                    "status",
                    "externalReference",
                    "failureReason",
                    "createdAt",
                    "confirmedAt"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "id": "DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58",
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "amount": "150.00",
                  "currency": "BRL",
                  "method": "PIX",
                  "status": "failed",
                  "externalReference": "psp-2026-000123",
                  "failureReason": "pagamento expirou no PSP",
                  "createdAt": "2026-09-25T14:08:02.771Z",
                  "confirmedAt": null
                }
              }
            }
          },
          "400": {
            "description": "Erro: `IDEMPOTENCY_KEY_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_KEY_REQUIRED",
                    "message": "O cabeçalho Idempotency-Key é obrigatório nesta operação",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `DEPOSIT_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "DEPOSIT_NOT_FOUND",
                    "message": "Depósito não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erro: `IDEMPOTENCY_CONFLICT`, `IDEMPOTENCY_IN_PROGRESS`, `DEPOSIT_NOT_PENDING`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_CONFLICT",
                    "message": "Idempotency-Key já usada com uma requisição diferente",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY='{\"reason\":\"pagamento expirou no PSP\"}'\nPATH_Q='/api/v1/deposits/DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58/fail'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'POST\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X POST \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"$BODY\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/deposits/DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58/fail\";\nconst body = JSON.stringify({\n  \"reason\": \"pagamento expirou no PSP\"\n});\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"POST\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": randomUUID(),\n  },\n  body,\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/deposits/DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58/fail\"\nbody = json.dumps({\n    \"reason\": \"pagamento expirou no PSP\"\n}, separators=(\",\", \":\"))\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"POST\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": str(uuid.uuid4()),\n}\nres = requests.request(\"POST\", BASE_URL + path, headers=headers, data=body)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/players/{playerId}/withdrawals": {
      "post": {
        "operationId": "requestWithdrawal",
        "summary": "Solicitar saque",
        "description": "Cria um pedido de saque na fila de análise do backoffice (aprovação e alçadas são da equipe). Exige KYC aprovado e jogador ativo, sem rollover de bônus pendente, e saldo real disponível descontados os saques ainda em aberto. O saldo é debitado no pagamento.",
        "tags": [
          "Saques"
        ],
        "parameters": [
          {
            "name": "playerId",
            "in": "path",
            "required": true,
            "schema": {
              "description": "Identificador do jogador no BetBackoffice",
              "type": "string",
              "minLength": 1
            },
            "description": "Identificador do jogador no BetBackoffice",
            "example": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Chave única por intenção (8–128 caracteres). Reenvie a mesma em retentativas.",
            "example": "6f1e2d3c-4b5a-4978-8a9b-0c1d2e3f4a5b",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "amount": {
                    "description": "Valor decimal positivo em string com até 2 casas, ex.: \"100.00\"",
                    "type": "string"
                  },
                  "currency": {
                    "description": "Deve ser a moeda do jogador",
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 3
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "PIX",
                      "TED",
                      "Cartão",
                      "Carteira digital"
                    ]
                  },
                  "destination": {
                    "description": "Destino do pagamento, ex.: chave PIX",
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 140
                  }
                },
                "required": [
                  "amount",
                  "currency",
                  "method",
                  "destination"
                ]
              },
              "example": {
                "amount": "50.00",
                "currency": "BRL",
                "method": "PIX",
                "destination": "ana.souza@exemplo.com"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "playerId": {
                      "type": "string"
                    },
                    "amount": {
                      "description": "Valor decimal em string com 2 casas, ex.: \"100.00\"",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "method": {
                      "type": "string",
                      "enum": [
                        "PIX",
                        "TED",
                        "Cartão",
                        "Carteira digital"
                      ]
                    },
                    "destination": {
                      "type": "string"
                    },
                    "status": {
                      "description": "under_review: em análise pela equipe; approved: aprovado, aguardando pagamento; paid: pago; rejected: recusado; cancelled: cancelado; failed: falhou",
                      "type": "string",
                      "enum": [
                        "under_review",
                        "approved",
                        "paid",
                        "rejected",
                        "cancelled",
                        "failed"
                      ]
                    },
                    "requestedAt": {
                      "type": "string"
                    },
                    "updatedAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "playerId",
                    "amount",
                    "currency",
                    "method",
                    "destination",
                    "status",
                    "requestedAt",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "id": "WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82",
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "amount": "50.00",
                  "currency": "BRL",
                  "method": "PIX",
                  "destination": "ana.souza@exemplo.com",
                  "status": "under_review",
                  "requestedAt": "2026-09-25T14:20:15.300Z",
                  "updatedAt": "2026-09-25T14:20:15.300Z"
                }
              }
            }
          },
          "400": {
            "description": "Erro: `IDEMPOTENCY_KEY_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_KEY_REQUIRED",
                    "message": "O cabeçalho Idempotency-Key é obrigatório nesta operação",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Erro: `INSUFFICIENT_BALANCE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INSUFFICIENT_BALANCE",
                    "message": "Saldo insuficiente",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`, `KYC_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `PLAYER_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PLAYER_NOT_FOUND",
                    "message": "Jogador não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erro: `IDEMPOTENCY_CONFLICT`, `IDEMPOTENCY_IN_PROGRESS`, `PLAYER_NOT_ACTIVE`, `RG_BLOCKED`, `BONUS_ROLLOVER_PENDING`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_CONFLICT",
                    "message": "Idempotency-Key já usada com uma requisição diferente",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`, `CURRENCY_MISMATCH`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY='{\"amount\":\"50.00\",\"currency\":\"BRL\",\"method\":\"PIX\",\"destination\":\"ana.souza@exemplo.com\"}'\nPATH_Q='/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/withdrawals'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'POST\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X POST \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"$BODY\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/withdrawals\";\nconst body = JSON.stringify({\n  \"amount\": \"50.00\",\n  \"currency\": \"BRL\",\n  \"method\": \"PIX\",\n  \"destination\": \"ana.souza@exemplo.com\"\n});\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"POST\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": randomUUID(),\n  },\n  body,\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/withdrawals\"\nbody = json.dumps({\n    \"amount\": \"50.00\",\n    \"currency\": \"BRL\",\n    \"method\": \"PIX\",\n    \"destination\": \"ana.souza@exemplo.com\"\n}, separators=(\",\", \":\"))\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"POST\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": str(uuid.uuid4()),\n}\nres = requests.request(\"POST\", BASE_URL + path, headers=headers, data=body)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/withdrawals/{withdrawalId}": {
      "get": {
        "operationId": "getWithdrawal",
        "summary": "Consultar saque",
        "tags": [
          "Saques"
        ],
        "parameters": [
          {
            "name": "withdrawalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82"
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "playerId": {
                      "type": "string"
                    },
                    "amount": {
                      "description": "Valor decimal em string com 2 casas, ex.: \"100.00\"",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "method": {
                      "type": "string",
                      "enum": [
                        "PIX",
                        "TED",
                        "Cartão",
                        "Carteira digital"
                      ]
                    },
                    "destination": {
                      "type": "string"
                    },
                    "status": {
                      "description": "under_review: em análise pela equipe; approved: aprovado, aguardando pagamento; paid: pago; rejected: recusado; cancelled: cancelado; failed: falhou",
                      "type": "string",
                      "enum": [
                        "under_review",
                        "approved",
                        "paid",
                        "rejected",
                        "cancelled",
                        "failed"
                      ]
                    },
                    "requestedAt": {
                      "type": "string"
                    },
                    "updatedAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "playerId",
                    "amount",
                    "currency",
                    "method",
                    "destination",
                    "status",
                    "requestedAt",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "id": "WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82",
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "amount": "50.00",
                  "currency": "BRL",
                  "method": "PIX",
                  "destination": "ana.souza@exemplo.com",
                  "status": "under_review",
                  "requestedAt": "2026-09-25T14:20:15.300Z",
                  "updatedAt": "2026-09-25T14:20:15.300Z"
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `WITHDRAWAL_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "WITHDRAWAL_NOT_FOUND",
                    "message": "Saque não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/withdrawals/WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'GET\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X GET \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/withdrawals/WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"GET\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"GET\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/withdrawals/WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"GET\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n}\nres = requests.request(\"GET\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/withdrawals/{withdrawalId}/cancel": {
      "post": {
        "operationId": "cancelWithdrawal",
        "summary": "Cancelar saque",
        "description": "Só é possível enquanto o saque ainda não foi aprovado pela equipe.",
        "tags": [
          "Saques"
        ],
        "parameters": [
          {
            "name": "withdrawalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Chave única por intenção (8–128 caracteres). Reenvie a mesma em retentativas.",
            "example": "6f1e2d3c-4b5a-4978-8a9b-0c1d2e3f4a5b",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "playerId": {
                      "type": "string"
                    },
                    "amount": {
                      "description": "Valor decimal em string com 2 casas, ex.: \"100.00\"",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "method": {
                      "type": "string",
                      "enum": [
                        "PIX",
                        "TED",
                        "Cartão",
                        "Carteira digital"
                      ]
                    },
                    "destination": {
                      "type": "string"
                    },
                    "status": {
                      "description": "under_review: em análise pela equipe; approved: aprovado, aguardando pagamento; paid: pago; rejected: recusado; cancelled: cancelado; failed: falhou",
                      "type": "string",
                      "enum": [
                        "under_review",
                        "approved",
                        "paid",
                        "rejected",
                        "cancelled",
                        "failed"
                      ]
                    },
                    "requestedAt": {
                      "type": "string"
                    },
                    "updatedAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "playerId",
                    "amount",
                    "currency",
                    "method",
                    "destination",
                    "status",
                    "requestedAt",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "id": "WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82",
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "amount": "50.00",
                  "currency": "BRL",
                  "method": "PIX",
                  "destination": "ana.souza@exemplo.com",
                  "status": "cancelled",
                  "requestedAt": "2026-09-25T14:20:15.300Z",
                  "updatedAt": "2026-09-25T14:20:15.300Z"
                }
              }
            }
          },
          "400": {
            "description": "Erro: `IDEMPOTENCY_KEY_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_KEY_REQUIRED",
                    "message": "O cabeçalho Idempotency-Key é obrigatório nesta operação",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `WITHDRAWAL_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "WITHDRAWAL_NOT_FOUND",
                    "message": "Saque não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erro: `IDEMPOTENCY_CONFLICT`, `IDEMPOTENCY_IN_PROGRESS`, `WITHDRAWAL_NOT_CANCELLABLE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_CONFLICT",
                    "message": "Idempotency-Key já usada com uma requisição diferente",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/withdrawals/WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82/cancel'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'POST\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X POST \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\" \\\n  -H \"Idempotency-Key: $(uuidgen)\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/withdrawals/WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82/cancel\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"POST\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": randomUUID(),\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/withdrawals/WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82/cancel\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"POST\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": str(uuid.uuid4()),\n}\nres = requests.request(\"POST\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/games": {
      "get": {
        "operationId": "listGames",
        "summary": "Catálogo de jogos",
        "tags": [
          "Jogos"
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "description": "Use como gameId ao criar a sessão",
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "category": {
                            "type": "string"
                          },
                          "active": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "category",
                          "active"
                        ],
                        "additionalProperties": false
                      }
                    }
                  },
                  "required": [
                    "data"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "data": [
                    {
                      "id": "rocket-crash",
                      "name": "Rocket Crash",
                      "category": "crash",
                      "active": true
                    },
                    {
                      "id": "mines",
                      "name": "Mines",
                      "category": "mines",
                      "active": true
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Erro: `PROVIDER_UNAVAILABLE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PROVIDER_UNAVAILABLE",
                    "message": "Game Provider indisponível",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/games'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'GET\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X GET \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/games\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"GET\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"GET\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/games\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"GET\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n}\nres = requests.request(\"GET\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/players/{playerId}/game-sessions": {
      "post": {
        "operationId": "createGameSession",
        "summary": "Criar sessão de jogo",
        "description": "Cria uma sessão de jogo com dinheiro real e devolve a `gameUrl`, que o seu front abre (ex.: em um iframe). Exige jogador ativo e KYC aprovado. A URL carrega um token de curta duração (30 minutos): **não a registre em logs nem a repasse a terceiros**. Cada chamada cria uma nova sessão (não usa `Idempotency-Key`).",
        "tags": [
          "Jogos"
        ],
        "parameters": [
          {
            "name": "playerId",
            "in": "path",
            "required": true,
            "schema": {
              "description": "Identificador do jogador no BetBackoffice",
              "type": "string",
              "minLength": 1
            },
            "description": "Identificador do jogador no BetBackoffice",
            "example": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "gameId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64
                  },
                  "locale": {
                    "default": "pt-BR",
                    "type": "string",
                    "pattern": "^[a-z]{2}(-[A-Z]{2})?$"
                  },
                  "device": {
                    "default": "desktop",
                    "type": "string",
                    "enum": [
                      "desktop",
                      "tablet",
                      "mobile"
                    ]
                  }
                },
                "required": [
                  "gameId"
                ]
              },
              "example": {
                "gameId": "rocket-crash",
                "locale": "pt-BR",
                "device": "desktop"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sessionId": {
                      "type": "string"
                    },
                    "gameUrl": {
                      "description": "URL para abrir o jogo; contém token de curta duração",
                      "type": "string"
                    },
                    "expiresAt": {
                      "description": "ISO 8601 UTC",
                      "type": "string"
                    }
                  },
                  "required": [
                    "sessionId",
                    "gameUrl",
                    "expiresAt"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "sessionId": "b3a1f6c2-49d0-4e7b-8a15-2c6d9e0f4b71",
                  "gameUrl": "https://games.exemplo.com/play/rocket-crash?token=…",
                  "expiresAt": "2026-09-25T14:45:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`, `KYC_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `PLAYER_NOT_FOUND`, `GAME_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PLAYER_NOT_FOUND",
                    "message": "Jogador não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erro: `PLAYER_NOT_ACTIVE`, `RG_BLOCKED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PLAYER_NOT_ACTIVE",
                    "message": "Jogador não está ativo",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "502": {
            "description": "Erro: `PROVIDER_UNAVAILABLE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PROVIDER_UNAVAILABLE",
                    "message": "Game Provider indisponível",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY='{\"gameId\":\"rocket-crash\",\"locale\":\"pt-BR\",\"device\":\"desktop\"}'\nPATH_Q='/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/game-sessions'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'POST\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X POST \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"$BODY\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/game-sessions\";\nconst body = JSON.stringify({\n  \"gameId\": \"rocket-crash\",\n  \"locale\": \"pt-BR\",\n  \"device\": \"desktop\"\n});\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"POST\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n  },\n  body,\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/game-sessions\"\nbody = json.dumps({\n    \"gameId\": \"rocket-crash\",\n    \"locale\": \"pt-BR\",\n    \"device\": \"desktop\"\n}, separators=(\",\", \":\"))\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"POST\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n}\nres = requests.request(\"POST\", BASE_URL + path, headers=headers, data=body)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/webhooks/test": {
      "post": {
        "operationId": "sendTestWebhook",
        "summary": "Enviar webhook de teste",
        "description": "Enfileira um evento `webhook.test` para a URL de webhook configurada para o seu operador, para validar a URL e a verificação de assinatura. A entrega é assíncrona (poucos segundos). A URL e o segredo são configurados pela equipe no backoffice.",
        "tags": [
          "Webhooks"
        ],
        "responses": {
          "202": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "eventId": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "eventId"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "eventId": "evt_5d2f8a01-7c39-4b6e-9a14-0e3b7c5d8f26"
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY=''\nPATH_Q='/api/v1/webhooks/test'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'POST\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X POST \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/webhooks/test\";\nconst body = \"\";\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"POST\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n  },\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/webhooks/test\"\nbody = \"\"\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"POST\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n}\nres = requests.request(\"POST\", BASE_URL + path, headers=headers)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/sandbox/players/{playerId}/kyc/decision": {
      "post": {
        "operationId": "sandboxDecideKyc",
        "summary": "Decidir o KYC (somente sandbox)",
        "description": "Simula a decisão da equipe de compliance para o KYC do jogador, para você completar o fluxo em teste sem depender de ninguém. Dispara o webhook `kyc.status_changed`. **Em produção esta rota responde `403 SANDBOX_ONLY`**: lá a decisão é da equipe.",
        "tags": [
          "Sandbox"
        ],
        "parameters": [
          {
            "name": "playerId",
            "in": "path",
            "required": true,
            "schema": {
              "description": "Identificador do jogador no BetBackoffice",
              "type": "string",
              "minLength": 1
            },
            "description": "Identificador do jogador no BetBackoffice",
            "example": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Chave única por intenção (8–128 caracteres). Reenvie a mesma em retentativas.",
            "example": "6f1e2d3c-4b5a-4978-8a9b-0c1d2e3f4a5b",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "aprovado",
                      "reprovado"
                    ]
                  },
                  "reason": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  }
                },
                "required": [
                  "status"
                ]
              },
              "example": {
                "status": "aprovado"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "description": "Situação atual da verificação do jogador",
                      "type": "string",
                      "enum": [
                        "nao_iniciado",
                        "pendente",
                        "em_analise",
                        "documento_solicitado",
                        "aprovado",
                        "reprovado",
                        "expirado"
                      ]
                    },
                    "case": {
                      "description": "Caso de KYC mais recente, se houver",
                      "anyOf": [
                        {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "documentType": {
                              "type": "string",
                              "enum": [
                                "RG",
                                "CNH",
                                "Passaporte",
                                "Comprovante de residência"
                              ]
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "nao_iniciado",
                                "pendente",
                                "em_analise",
                                "documento_solicitado",
                                "aprovado",
                                "reprovado",
                                "expirado"
                              ]
                            },
                            "submittedAt": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "id",
                            "documentType",
                            "status",
                            "submittedAt"
                          ],
                          "additionalProperties": false
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "status",
                    "case"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "status": "aprovado",
                  "case": {
                    "id": "KYC-9e1f5a3c-6b24-4d78-a0c5-3f8b2d7e1a64",
                    "documentType": "RG",
                    "status": "aprovado",
                    "submittedAt": "2026-09-25T14:05:40.120Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Erro: `IDEMPOTENCY_KEY_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_KEY_REQUIRED",
                    "message": "O cabeçalho Idempotency-Key é obrigatório nesta operação",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`, `SANDBOX_ONLY`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `PLAYER_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "PLAYER_NOT_FOUND",
                    "message": "Jogador não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erro: `IDEMPOTENCY_CONFLICT`, `IDEMPOTENCY_IN_PROGRESS`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_CONFLICT",
                    "message": "Idempotency-Key já usada com uma requisição diferente",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY='{\"status\":\"aprovado\"}'\nPATH_Q='/api/v1/sandbox/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/kyc/decision'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'POST\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X POST \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"$BODY\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/sandbox/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/kyc/decision\";\nconst body = JSON.stringify({\n  \"status\": \"aprovado\"\n});\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"POST\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": randomUUID(),\n  },\n  body,\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/sandbox/players/PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34/kyc/decision\"\nbody = json.dumps({\n    \"status\": \"aprovado\"\n}, separators=(\",\", \":\"))\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"POST\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": str(uuid.uuid4()),\n}\nres = requests.request(\"POST\", BASE_URL + path, headers=headers, data=body)\nprint(res.status_code, res.json())"
          }
        ]
      }
    },
    "/sandbox/withdrawals/{withdrawalId}/decision": {
      "post": {
        "operationId": "sandboxDecideWithdrawal",
        "summary": "Decidir um saque (somente sandbox)",
        "description": "Simula a análise da equipe: `approve` (em análise → aprovado), `reject` (recusa) ou `pay` (aprovado → pago, debitando a carteira). Dispara `withdrawal.status_changed`. **Em produção responde `403 SANDBOX_ONLY`.**",
        "tags": [
          "Sandbox"
        ],
        "parameters": [
          {
            "name": "withdrawalId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1
            },
            "example": "WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82"
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "Chave única por intenção (8–128 caracteres). Reenvie a mesma em retentativas.",
            "example": "6f1e2d3c-4b5a-4978-8a9b-0c1d2e3f4a5b",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 128
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "decision": {
                    "type": "string",
                    "enum": [
                      "approve",
                      "reject",
                      "pay"
                    ]
                  }
                },
                "required": [
                  "decision"
                ]
              },
              "example": {
                "decision": "approve"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "playerId": {
                      "type": "string"
                    },
                    "amount": {
                      "description": "Valor decimal em string com 2 casas, ex.: \"100.00\"",
                      "type": "string",
                      "pattern": "^-?\\d+\\.\\d{2}$"
                    },
                    "currency": {
                      "type": "string"
                    },
                    "method": {
                      "type": "string",
                      "enum": [
                        "PIX",
                        "TED",
                        "Cartão",
                        "Carteira digital"
                      ]
                    },
                    "destination": {
                      "type": "string"
                    },
                    "status": {
                      "description": "under_review: em análise pela equipe; approved: aprovado, aguardando pagamento; paid: pago; rejected: recusado; cancelled: cancelado; failed: falhou",
                      "type": "string",
                      "enum": [
                        "under_review",
                        "approved",
                        "paid",
                        "rejected",
                        "cancelled",
                        "failed"
                      ]
                    },
                    "requestedAt": {
                      "type": "string"
                    },
                    "updatedAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "playerId",
                    "amount",
                    "currency",
                    "method",
                    "destination",
                    "status",
                    "requestedAt",
                    "updatedAt"
                  ],
                  "additionalProperties": false
                },
                "example": {
                  "id": "WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82",
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "amount": "50.00",
                  "currency": "BRL",
                  "method": "PIX",
                  "destination": "ana.souza@exemplo.com",
                  "status": "approved",
                  "requestedAt": "2026-09-25T14:20:15.300Z",
                  "updatedAt": "2026-09-25T14:20:15.300Z"
                }
              }
            }
          },
          "400": {
            "description": "Erro: `IDEMPOTENCY_KEY_REQUIRED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_KEY_REQUIRED",
                    "message": "O cabeçalho Idempotency-Key é obrigatório nesta operação",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Erro: `INVALID_CREDENTIALS`, `INVALID_SIGNATURE`, `TIMESTAMP_OUT_OF_RANGE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INVALID_CREDENTIALS",
                    "message": "Credenciais inválidas",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Erro: `OPERATOR_SUSPENDED`, `FORBIDDEN_IP`, `SANDBOX_ONLY`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "OPERATOR_SUSPENDED",
                    "message": "Operador suspenso",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Erro: `WITHDRAWAL_NOT_FOUND`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "WITHDRAWAL_NOT_FOUND",
                    "message": "Saque não encontrado",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Erro: `IDEMPOTENCY_CONFLICT`, `IDEMPOTENCY_IN_PROGRESS`, `INVALID_WITHDRAWAL_STATE`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "IDEMPOTENCY_CONFLICT",
                    "message": "Idempotency-Key já usada com uma requisição diferente",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Erro: `VALIDATION_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "VALIDATION_ERROR",
                    "message": "Dados inválidos",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05",
                    "details": {
                      "in": "body",
                      "issues": [
                        {
                          "path": "cpf",
                          "message": "CPF inválido"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Erro: `RATE_LIMITED`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Limite de requisições excedido",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Erro: `INTERNAL_ERROR`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "example": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Erro interno",
                    "requestId": "req_8d0c3a9e-5b71-4f24-a6c8-1e9d3f7b2a05"
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "Shell",
            "label": "curl (assinado)",
            "source": "# Defina API_BASE_URL (opcional), OPERATOR_KEY e OPERATOR_SECRET no ambiente.\nBODY='{\"decision\":\"approve\"}'\nPATH_Q='/api/v1/sandbox/withdrawals/WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82/decision'\nTS=$(date +%s)\nBODY_HASH=$(printf '%s' \"$BODY\" | openssl dgst -sha256 -hex | sed 's/^.* //')\nCANONICAL=$(printf 'POST\\n%s\\n%s\\n%s' \"$PATH_Q\" \"$TS\" \"$BODY_HASH\")\nSIG=$(printf '%s' \"$CANONICAL\" | openssl dgst -sha256 -hmac \"$OPERATOR_SECRET\" -hex | sed 's/^.* //')\n\ncurl -X POST \"${API_BASE_URL:-https://backoffice.betfoguete.bet}$PATH_Q\" \\\n  -H \"X-Operator-Key: $OPERATOR_KEY\" \\\n  -H \"X-Timestamp: $TS\" \\\n  -H \"X-Signature: $SIG\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d \"$BODY\""
          },
          {
            "lang": "JavaScript",
            "label": "Node.js (assinado)",
            "source": "import { createHash, createHmac, randomUUID } from \"node:crypto\";\n\nconst BASE_URL = process.env.API_BASE_URL ?? \"https://backoffice.betfoguete.bet\";\nconst path = \"/api/v1/sandbox/withdrawals/WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82/decision\";\nconst body = JSON.stringify({\n  \"decision\": \"approve\"\n});\n\nconst timestamp = String(Math.floor(Date.now() / 1000));\nconst canonical = [\"POST\", path, timestamp, createHash(\"sha256\").update(body).digest(\"hex\")].join(\"\\n\");\nconst signature = createHmac(\"sha256\", process.env.OPERATOR_SECRET).update(canonical).digest(\"hex\");\n\nconst res = await fetch(BASE_URL + path, {\n  method: \"POST\",\n  headers: {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": process.env.OPERATOR_KEY,\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": randomUUID(),\n  },\n  body,\n});\nconsole.log(res.status, await res.json());"
          },
          {
            "lang": "Python",
            "label": "Python (assinado)",
            "source": "import hashlib, hmac, json, os, time, uuid\nimport requests\n\nBASE_URL = os.environ.get(\"API_BASE_URL\", \"https://backoffice.betfoguete.bet\")\npath = \"/api/v1/sandbox/withdrawals/WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82/decision\"\nbody = json.dumps({\n    \"decision\": \"approve\"\n}, separators=(\",\", \":\"))\n\ntimestamp = str(int(time.time()))\ncanonical = \"\\n\".join([\"POST\", path, timestamp, hashlib.sha256(body.encode()).hexdigest()])\nsignature = hmac.new(os.environ[\"OPERATOR_SECRET\"].encode(), canonical.encode(), hashlib.sha256).hexdigest()\n\nheaders = {\n    \"Content-Type\": \"application/json\",\n    \"X-Operator-Key\": os.environ[\"OPERATOR_KEY\"],\n    \"X-Timestamp\": timestamp,\n    \"X-Signature\": signature,\n    \"Idempotency-Key\": str(uuid.uuid4()),\n}\nres = requests.request(\"POST\", BASE_URL + path, headers=headers, data=body)\nprint(res.status_code, res.json())"
          }
        ]
      }
    }
  },
  "webhooks": {
    "player.status_changed": {
      "post": {
        "operationId": "webhook_player_status_changed",
        "summary": "Situação da conta do jogador mudou",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Identificador do evento; use para deduplicar entregas repetidas",
                    "type": "string"
                  },
                  "type": {
                    "type": "string",
                    "const": "player.status_changed"
                  },
                  "createdAt": {
                    "description": "ISO 8601 UTC",
                    "type": "string"
                  },
                  "apiVersion": {
                    "type": "string"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "playerId": {
                        "type": "string"
                      },
                      "externalId": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "ativo",
                          "suspenso",
                          "bloqueado",
                          "autoexcluido",
                          "encerrado",
                          "restrito"
                        ]
                      },
                      "previousStatus": {
                        "anyOf": [
                          {
                            "type": "string",
                            "enum": [
                              "ativo",
                              "suspenso",
                              "bloqueado",
                              "autoexcluido",
                              "encerrado",
                              "restrito"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "playerId",
                      "externalId",
                      "status",
                      "previousStatus"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "createdAt",
                  "apiVersion",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "evt_5d2f8a01-7c39-4b6e-9a14-0e3b7c5d8f26",
                "type": "player.status_changed",
                "createdAt": "2026-09-25T14:09:30.004Z",
                "apiVersion": "1.1.0",
                "data": {
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "externalId": "jogador-123",
                  "status": "suspenso",
                  "previousStatus": "ativo"
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebimento confirmado"
          }
        }
      }
    },
    "kyc.status_changed": {
      "post": {
        "operationId": "webhook_kyc_status_changed",
        "summary": "Situação do KYC mudou",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Identificador do evento; use para deduplicar entregas repetidas",
                    "type": "string"
                  },
                  "type": {
                    "type": "string",
                    "const": "kyc.status_changed"
                  },
                  "createdAt": {
                    "description": "ISO 8601 UTC",
                    "type": "string"
                  },
                  "apiVersion": {
                    "type": "string"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "playerId": {
                        "type": "string"
                      },
                      "externalId": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "nao_iniciado",
                          "pendente",
                          "em_analise",
                          "documento_solicitado",
                          "aprovado",
                          "reprovado",
                          "expirado"
                        ]
                      },
                      "previousStatus": {
                        "anyOf": [
                          {
                            "type": "string",
                            "enum": [
                              "nao_iniciado",
                              "pendente",
                              "em_analise",
                              "documento_solicitado",
                              "aprovado",
                              "reprovado",
                              "expirado"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "playerId",
                      "externalId",
                      "status",
                      "previousStatus"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "createdAt",
                  "apiVersion",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "evt_5d2f8a01-7c39-4b6e-9a14-0e3b7c5d8f26",
                "type": "kyc.status_changed",
                "createdAt": "2026-09-25T14:09:30.004Z",
                "apiVersion": "1.1.0",
                "data": {
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "externalId": "jogador-123",
                  "status": "aprovado",
                  "previousStatus": "em_analise"
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebimento confirmado"
          }
        }
      }
    },
    "deposit.confirmed": {
      "post": {
        "operationId": "webhook_deposit_confirmed",
        "summary": "Depósito confirmado e creditado",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Identificador do evento; use para deduplicar entregas repetidas",
                    "type": "string"
                  },
                  "type": {
                    "type": "string",
                    "const": "deposit.confirmed"
                  },
                  "createdAt": {
                    "description": "ISO 8601 UTC",
                    "type": "string"
                  },
                  "apiVersion": {
                    "type": "string"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "playerId": {
                        "type": "string"
                      },
                      "amount": {
                        "description": "Valor decimal em string com 2 casas, ex.: \"100.00\"",
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$"
                      },
                      "currency": {
                        "type": "string"
                      },
                      "method": {
                        "type": "string",
                        "enum": [
                          "PIX",
                          "TED",
                          "Cartão",
                          "Carteira digital"
                        ]
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "pending",
                          "confirmed",
                          "failed",
                          "expired"
                        ]
                      },
                      "externalReference": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "failureReason": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "createdAt": {
                        "type": "string"
                      },
                      "confirmedAt": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "id",
                      "playerId",
                      "amount",
                      "currency",
                      "method",
                      "status",
                      "externalReference",
                      "failureReason",
                      "createdAt",
                      "confirmedAt"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "createdAt",
                  "apiVersion",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "evt_5d2f8a01-7c39-4b6e-9a14-0e3b7c5d8f26",
                "type": "deposit.confirmed",
                "createdAt": "2026-09-25T14:09:30.004Z",
                "apiVersion": "1.1.0",
                "data": {
                  "id": "DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58",
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "amount": "150.00",
                  "currency": "BRL",
                  "method": "PIX",
                  "status": "confirmed",
                  "externalReference": "psp-2026-000123",
                  "failureReason": null,
                  "createdAt": "2026-09-25T14:08:02.771Z",
                  "confirmedAt": "2026-09-25T14:09:30.004Z"
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebimento confirmado"
          }
        }
      }
    },
    "deposit.failed": {
      "post": {
        "operationId": "webhook_deposit_failed",
        "summary": "Depósito marcado como não concretizado",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Identificador do evento; use para deduplicar entregas repetidas",
                    "type": "string"
                  },
                  "type": {
                    "type": "string",
                    "const": "deposit.failed"
                  },
                  "createdAt": {
                    "description": "ISO 8601 UTC",
                    "type": "string"
                  },
                  "apiVersion": {
                    "type": "string"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "playerId": {
                        "type": "string"
                      },
                      "amount": {
                        "description": "Valor decimal em string com 2 casas, ex.: \"100.00\"",
                        "type": "string",
                        "pattern": "^-?\\d+\\.\\d{2}$"
                      },
                      "currency": {
                        "type": "string"
                      },
                      "method": {
                        "type": "string",
                        "enum": [
                          "PIX",
                          "TED",
                          "Cartão",
                          "Carteira digital"
                        ]
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "pending",
                          "confirmed",
                          "failed",
                          "expired"
                        ]
                      },
                      "externalReference": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "failureReason": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "createdAt": {
                        "type": "string"
                      },
                      "confirmedAt": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "id",
                      "playerId",
                      "amount",
                      "currency",
                      "method",
                      "status",
                      "externalReference",
                      "failureReason",
                      "createdAt",
                      "confirmedAt"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "createdAt",
                  "apiVersion",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "evt_5d2f8a01-7c39-4b6e-9a14-0e3b7c5d8f26",
                "type": "deposit.failed",
                "createdAt": "2026-09-25T14:09:30.004Z",
                "apiVersion": "1.1.0",
                "data": {
                  "id": "DEP-7b2e4c10-5a93-4f8e-b1d6-0c9a3e7d2f58",
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "amount": "150.00",
                  "currency": "BRL",
                  "method": "PIX",
                  "status": "failed",
                  "externalReference": "psp-2026-000123",
                  "failureReason": "pagamento expirou no PSP",
                  "createdAt": "2026-09-25T14:08:02.771Z",
                  "confirmedAt": null
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebimento confirmado"
          }
        }
      }
    },
    "withdrawal.status_changed": {
      "post": {
        "operationId": "webhook_withdrawal_status_changed",
        "summary": "Situação do saque mudou",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Identificador do evento; use para deduplicar entregas repetidas",
                    "type": "string"
                  },
                  "type": {
                    "type": "string",
                    "const": "withdrawal.status_changed"
                  },
                  "createdAt": {
                    "description": "ISO 8601 UTC",
                    "type": "string"
                  },
                  "apiVersion": {
                    "type": "string"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "playerId": {
                        "type": "string"
                      },
                      "externalId": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ]
                      },
                      "withdrawalId": {
                        "type": "string"
                      },
                      "amount": {
                        "type": "string"
                      },
                      "currency": {
                        "type": "string"
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "under_review",
                          "approved",
                          "paid",
                          "rejected",
                          "cancelled",
                          "failed"
                        ]
                      },
                      "previousStatus": {
                        "anyOf": [
                          {
                            "type": "string",
                            "enum": [
                              "under_review",
                              "approved",
                              "paid",
                              "rejected",
                              "cancelled",
                              "failed"
                            ]
                          },
                          {
                            "type": "null"
                          }
                        ]
                      }
                    },
                    "required": [
                      "playerId",
                      "externalId",
                      "withdrawalId",
                      "amount",
                      "currency",
                      "status",
                      "previousStatus"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "createdAt",
                  "apiVersion",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "evt_5d2f8a01-7c39-4b6e-9a14-0e3b7c5d8f26",
                "type": "withdrawal.status_changed",
                "createdAt": "2026-09-25T14:09:30.004Z",
                "apiVersion": "1.1.0",
                "data": {
                  "playerId": "PLU-3f1c9a2e-8d4b-4e6a-9c1d-2b7e5f0a1c34",
                  "externalId": "jogador-123",
                  "withdrawalId": "WD-c41d9e07-2b6a-4d35-8f10-7e5b9a3c6d82",
                  "amount": "50.00",
                  "currency": "BRL",
                  "status": "approved",
                  "previousStatus": "under_review"
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebimento confirmado"
          }
        }
      }
    },
    "webhook.test": {
      "post": {
        "operationId": "webhook_webhook_test",
        "summary": "Evento de teste (POST /webhooks/test)",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "description": "Identificador do evento; use para deduplicar entregas repetidas",
                    "type": "string"
                  },
                  "type": {
                    "type": "string",
                    "const": "webhook.test"
                  },
                  "createdAt": {
                    "description": "ISO 8601 UTC",
                    "type": "string"
                  },
                  "apiVersion": {
                    "type": "string"
                  },
                  "data": {
                    "type": "object",
                    "properties": {
                      "message": {
                        "type": "string"
                      }
                    },
                    "required": [
                      "message"
                    ],
                    "additionalProperties": false
                  }
                },
                "required": [
                  "id",
                  "type",
                  "createdAt",
                  "apiVersion",
                  "data"
                ],
                "additionalProperties": false
              },
              "example": {
                "id": "evt_5d2f8a01-7c39-4b6e-9a14-0e3b7c5d8f26",
                "type": "webhook.test",
                "createdAt": "2026-09-25T14:09:30.004Z",
                "apiVersion": "1.1.0",
                "data": {
                  "message": "Webhook de teste do BetBackoffice"
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Recebimento confirmado"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "OperatorKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Operator-Key",
        "description": "Chave da credencial do operador."
      },
      "Timestamp": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Timestamp",
        "description": "Epoch em segundos (±5 min)."
      },
      "Signature": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Signature",
        "description": "hex(HMAC-SHA256(secret, METODO\\nCAMINHO?QUERY\\nTIMESTAMP\\nSHA256_HEX(corpo)))."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "description": "Código estável do erro",
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "requestId": {
                "description": "Identificador da requisição, para suporte",
                "type": "string"
              },
              "details": {}
            },
            "required": [
              "code",
              "message",
              "requestId"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error"
        ],
        "additionalProperties": false
      }
    }
  }
}
