Documentação · v1

API de salas Guard Salas

Crie salas de Free Fire, acompanhe os jogadores e inicie a partida por API. Todas as chamadas usam esta base:

base url
https://guard-salas-api.squareweb.app/api
Cada sala criada consome 1 sala do seu saldo no bot da Guard Salas, o mesmo saldo que você usa no Discord. Quem tem a assinatura Salas Infinitas não gasta saldo. Consultar sala, ver jogadores, iniciar a partida e expulsar jogador não consomem. Se a criação falhar, o saldo é devolvido automaticamente.

Você gera e revoga as suas keys no painel, em guardmed.online/painel/api, entrando com o Discord. Para ter saldo, compre salas no bot ou no painel (Saldo e compras).

Quickstart

Com a sua key em mãos (gere em guardmed.online/painel/api), crie a primeira sala. Troque SUA_KEY pela sua chave:

curl -X POST "https://guard-salas-api.squareweb.app/api/v1/rooms" \
  -H "X-API-Key: SUA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"modo":1,"nome":"Guard Arena","senha":"67","auto_start_min":5}'

A resposta traz o room_id e a password para os jogadores entrarem, e o session_id, que você usa para acompanhar e controlar a sala.

Autenticação

Envie a key em todas as rotas /v1. Os dois formatos abaixo são equivalentes; use um deles.

CampoTipoObrigatórioDescrição
X-API-KeyheaderSim*Sua key, começando com fsk_live_.
AuthorizationheaderSim*Alternativa: Bearer fsk_live_...
Idempotency-KeyheaderRecomendadoUm UUID único por operação em POST. Repetir a mesma chave devolve o resultado anterior, sem criar outra sala nem cobrar de novo.
Content-TypeheaderCom corpoapplication/json sempre que houver corpo JSON.
Trate a key como uma senha. Não a coloque em código público, em front-end ou em repositório. Se ela vazar, revogue no painel (guardmed.online/painel/api) e gere outra: a antiga para de funcionar na hora.

Fluxo recomendado

PassoO que fazer
1GET /v1/modes para listar os modos.
2POST /v1/rooms para criar a sala e receber ID e senha.
3GET /v1/rooms/{id}/players a cada ~5 segundos para ver quem entrou.
4POST /v1/rooms/{id}/kick se precisar barrar alguém.
5POST /v1/rooms/{id}/start para dar o GO, ou deixe o auto-start agir.
6GET /v1/rooms/{id}/result a cada ~30 segundos até finished: true para pegar o placar.

Modos de sala

Use o número no campo modo. Todos os modos são Contra Squad para 8 jogadores (4 contra 4) e já vêm com a configuração padrão abaixo, sem você precisar mandar mais nada.

modoNomeLojaRounds padrão
1Apostado Sem Carregamento17 itens13
2Apostado Com Carregamento17 itens13
3Apostado Gelo Infinito17 itens13
4Apostado Só Headshot17 itens13
5Full UMP e XM810 itens (UMP, XM8, Desert Eagle, Mini Uzi e equipamento)13

Para mudar só a quantidade de rounds em uma sala, envie rounds (de 1 a 13) na criação. Sem esse campo a sala usa os 13 rounds padrão do modo.

Criar sala

POST/v1/roomsconsome 1 sala

Cria a sala e devolve ID e senha. Sem senha, usamos 67. A partida inicia sozinha quando o tempo de auto_start_min acaba.

CampoTipoObrigatórioDescrição
modointegerNãoDe 1 a 5. Padrão 1. Também aceita mode_id.
nomestringNãoAté 30 caracteres. Padrão "Guard Salas".
senhastringNãoSomente números, até 16 dígitos. Padrão 67.
auto_start_minintegerNãoInício automático de 1 a 30 minutos. Padrão 5.
roundsintegerNãoQuantidade de rounds da partida, de 1 a 13. Sem este campo, vale o padrão do modo (13 rounds).
votacaobooleanNãoVotação de início pelo chat da sala. Padrão true; envie false para desligar.
votosintegerNãoMínimo de votos para iniciar (2 a 8). Sem este campo, todos os jogadores da sala precisam votar.

Exemplo

curl -X POST "https://guard-salas-api.squareweb.app/api/v1/rooms" \
  -H "X-API-Key: SUA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"modo":1,"nome":"Guard Arena","senha":"67","auto_start_min":5}'

Resposta

200 OK
{
  "status": "created",
  "credits": 41,
  "session_id": "sess_1789780738514_4b176f44",
  "room_id": "4249447",
  "password": "67",
  "name": "Guard Arena",
  "mode": 1,
  "auto_start_min": 5,
  "expires_at": 1789781038,
  "room_url": "https://ffshare.garena.com/?region=BR&...&room_id=4249447"
}

Guarde o session_id: é ele que identifica a sala nas outras rotas. credits é o seu saldo restante no bot depois da cobrança, e vem null para quem tem Salas Infinitas. expires_at é o horário do auto-start, em segundos Unix.

CódigoQuando
400Senha ou campo inválido.
401Key ausente, inválida ou revogada.
402Saldo de salas insuficiente.
404Modo não encontrado.
429Você criou salas demais em pouco tempo (máximo de 10 por minuto). Aguarde o tempo do Retry-After. Não cobra.
503Nenhuma conta disponível no momento. Não cobra; tente de novo em alguns segundos.
502Falha ao criar a sala. O saldo é devolvido.

Consultar sala

GET/v1/rooms/{session_id}sem custo
curl -X GET "https://guard-salas-api.squareweb.app/api/v1/rooms/SESSION_ID" \
  -H "X-API-Key: SUA_KEY"

Resposta

200 OK
{
  "status": "ok",
  "session_id": "sess_1789780738514_4b176f44",
  "room": {
    "room_id": "4249447",
    "name": "Guard Arena",
    "password": "67",
    "mode": "cs_8_sem_carregamento",
    "state": "waiting",
    "started": false,
    "expires_at": 1789781038
  },
  "player_count": 3,
  "spectator_count": 0
}

state pode ser waiting, starting, started ou closed.

CódigoQuando
404Sala não encontrada ou não pertence à sua key.

Jogadores

GET/v1/rooms/{session_id}/playerssem custo

Lista quem entrou na sala, com time, slot, plataforma e o loadout quando já estiver disponível. O bot dono da sala não aparece na lista.

curl -X GET "https://guard-salas-api.squareweb.app/api/v1/rooms/SESSION_ID/players" \
  -H "X-API-Key: SUA_KEY"

Resposta

200 OK
{
  "status": "ok",
  "count": 1,
  "room_id": "4249447",
  "session_id": "sess_1789780738514_4b176f44",
  "players": [
    {
      "uid": "1234567890",
      "nickname": "Player",
      "team": 1,
      "slot": 0,
      "platform": "mobile",
      "loadout": {
        "status": "ready",
        "character": null,
        "skills": [],
        "pet": null
      }
    }
  ]
}
CampoTipoObrigatórioDescrição
uidstringSimUID do jogador, como texto.
nicknamestringSimNick observado na sala. Pode vir vazio durante a sincronização.
team / slotintegerNãoTime (1 ou 2) e posição.
platformstringSimmobile ou emulator. Serve para barrar emulador antes do GO.
loadout.statusstringSimready quando capturado; pending enquanto aguarda. Pending não é erro: consulte de novo em alguns segundos.
loadout.characterobjectNãoPersonagem do jogador: name e icon_url vêm da habilidade ativa equipada; id é o avatar_id do perfil. null enquanto o loadout não chega. Sem habilidade ativa equipada, name vem null.
loadout.skillsarraySimHabilidades equipadas, em ordem de slot: skill_id, character_name, skill_type (active ou passive) e icon_url (retrato do personagem). Quando há ícone da habilidade, vêm também ability_icon_url e ability_icon_large_url.
loadout.petobjectNãoPet equipado: name, nickname, level, skill_id e icon_url; skill_icon_url traz o ícone da habilidade do pet quando existe. null quando o jogador não usa pet.

Iniciar partida

POST/v1/rooms/{session_id}/startsem custo

Dá o GO. A resposta confirma que o comando foi aceito; a partida carrega em seguida. A confirmação pode levar alguns segundos, então use timeout de pelo menos 60 s.

curl -X POST "https://guard-salas-api.squareweb.app/api/v1/rooms/SESSION_ID/start" \
  -H "X-API-Key: SUA_KEY"
200 OK
{
  "status": "started",
  "room_id": "4249447",
  "session_id": "sess_1789780738514_4b176f44",
  "credits": 41
}
CódigoQuando
404Sala não encontrada.
409A sala já está iniciando ou foi encerrada.
502O jogo não confirmou o início.

Resultado da partida

GET/v1/rooms/{session_id}/resultsem custo

Devolve o placar quando a partida termina. A API tira uma foto do perfil de cada jogador antes do início e compara de tempos em tempos: quando o perfil de alguém muda, a partida acabou e a diferença vira o placar. Enquanto isso não acontece, a resposta traz finished: false.

curl -X GET "https://guard-salas-api.squareweb.app/api/v1/rooms/SESSION_ID/result" \
  -H "X-API-Key: SUA_KEY"

Enquanto a partida não terminou

200 OK
{
  "status": "in_progress",
  "finished": false,
  "room_id": "4249447",
  "session_id": "sess_1789780738514_4b176f44",
  "jogadores": 8
}

Partida encerrada

200 OK
{
  "status": "ok",
  "finished": true,
  "room_id": "4249447",
  "session_id": "sess_1789780738514_4b176f44",
  "total": 8,
  "jogaram": 8,
  "mvp": "123456789",
  "mvp_nickname": "Fulano",
  "mvp_kills": 12,
  "vencedores": [
    "Fulano",
    "Ciclano"
  ],
  "vencedores_uids": [
    "123456789",
    "987654322"
  ],
  "winning_team": 1,
  "players": [
    {
      "uid": "123456789",
      "nickname": "Fulano",
      "team": 1,
      "kills": 12,
      "vitorias": 1,
      "partidas": 1,
      "dano": 1840,
      "jogou": true,
      "deltas": {}
    }
  ]
}
CampoTipoObrigatórioDescrição
statusstringSimwaiting (sala aberta), in_progress (partida rolando), ok (encerrada) ou unavailable (nenhuma mudança detectada no prazo).
finishedbooleanSimtrue só quando o placar está pronto.
mvp / mvp_killsstring / integerNãoJogador com mais kills; em empate, o de maior dano. null se ninguém pontuou.
vencedores / vencedores_uids / winning_teamarray / array / integerNãoNomes e UIDs de quem somou vitória, e o time deles.
players[].kills / vitorias / partidasintegerSimO que o jogador fez nesta partida (perfil depois menos perfil antes).
players[].jogoubooleanSimfalse para quem não teve nenhuma mudança no perfil.

O placar sai alguns segundos depois do fim da partida, porque o jogo demora para atualizar os perfis. Consulte a cada 30 segundos; a rota não cobra sala. Só jogadores que estavam na sala no início entram no resultado.

CódigoQuando
404Sala não encontrada ou de outra key.

Votação no chat

Todas as salas trazem um assistente no chat, sem custo e sem nenhuma chamada extra. Ele avisa quando alguém entra (com o nome) e explica como iniciar. Os jogadores votam escrevendo .start no chat da sala.

RegraComo funciona
LiberaçãoA votação só libera 1 minuto depois da sala criada; votos antes disso são recusados.
ContagemO bot informa cada voto, por exemplo Fulano votou para iniciar (2/4).
Quem saiSe um jogador sai da sala, o voto dele deixa de contar, e o bot avisa.
Quem votaSó jogadores que estão na sala; cada um vale um voto.
InícioQuando todos votam, a partida inicia com contagem 3, 2, 1. Não inicia com menos de 2 jogadores.
AutomáticoO início por tempo (auto_start_min) continua valendo se ninguém votar.

Use votos na criação para exigir só uma quantidade mínima de votos, ou votacao: false para desligar o assistente.

Expulsar jogador

POST/v1/rooms/{session_id}/kicksem custo

Remove um jogador da sala. Use o mesmo uid retornado em /players.

curl -X POST "https://guard-salas-api.squareweb.app/api/v1/rooms/SESSION_ID/kick" \
  -H "X-API-Key: SUA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"uid":"1234567890"}'
200 OK
{
  "status": "kicked",
  "uid": "1234567890",
  "room_id": "4249447",
  "session_id": "sess_1789780738514_4b176f44"
}
CódigoQuando
400uid ausente ou inválido.
404Sala não encontrada.

Editar sala

POST/v1/rooms/{session_id}/editsem custo

Troca o modo, o nome, a senha e/ou os rounds de uma sala que ainda não começou. Envie só o que quer mudar. Também aceita PATCH no mesmo endereço.

O jogo não tem um comando de editar, então a sala é refeita por baixo: o session_id continua o mesmo, mas o room_id muda (e a senha, se você trocar). Guarde o novo room_id da resposta. Não gasta saldo. Se houver jogadores no lobby, a troca derrubaria todos: a API responde 409 e só faz com "force": true.
CampoTipoObrigatórioDescrição
modointeger | stringNãoNovo modo: 1 a 5 ou um modo customizado (cm_...). Sem este campo, mantém o modo atual.
nomestringNãoNovo nome da sala (até 30 caracteres).
senhastringNãoNova senha, só números (até 16 dígitos).
roundsintegerNãoNovos rounds, de 1 a 13.
forcebooleanNãoConfirma a troca mesmo com jogadores no lobby (eles são derrubados).
curl -X POST "https://guard-salas-api.squareweb.app/api/v1/rooms/SESSION_ID/edit" \
  -H "X-API-Key: SUA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"modo":3,"senha":"45"}'
200 OK
{
  "status": "edited",
  "session_id": "sess_1789780738514_4b176f44",
  "room_id": "4249999",
  "previous_room_id": "4249447",
  "password": "45",
  "name": "Guard Arena",
  "mode": 3,
  "rounds": null,
  "expires_at": 1789781038,
  "room_url": "https://ffshare.garena.com/?region=BR&...&room_id=4249999"
}
CódigoQuando
400Modo, senha ou rounds inválidos.
404Sala não encontrada ou modo inexistente.
409A sala já começou, ou há jogadores no lobby (sem force).
429Trocas ou criações demais em pouco tempo.
503Nenhuma conta livre agora (a troca usa uma conta a mais por instantes).

Encerrar sala

POST/v1/rooms/{session_id}/releasesem custo

Encerra a sala agora e libera a conta que a hospedava. Use quando ninguém mais vai entrar. Não devolve saldo. Uma sala em início não pode ser encerrada (409).

curl -X POST "https://guard-salas-api.squareweb.app/api/v1/rooms/SESSION_ID/release" \
  -H "X-API-Key: SUA_KEY"
200 OK
{
  "status": "released",
  "room_id": "4249447",
  "session_id": "sess_1789780738514_4b176f44",
  "ok": true
}
CódigoQuando
404Sala não encontrada ou já encerrada.
409A sala está iniciando; aguarde.

Modos customizados

Crie o seu próprio modo escolhendo os itens da loja, os rounds e a moeda por round. O modo fica salvo na sua key e devolve um id (cm_...) que você usa no campo modo ao criar salas. Ele parte de um dos 5 modos base, que definem as demais regras da sala (carregamento, headshot, gelo).

GET/v1/itemssem custo

Catálogo de itens que podem entrar na loja: id, name, category (arma ou equipamento) e o price padrão. Alguns itens ainda aparecem como Item #N, sem nome conhecido; o id funciona igual.

curl -X GET "https://guard-salas-api.squareweb.app/api/v1/items" \
  -H "X-API-Key: SUA_KEY"
POST/v1/modessem custo
CampoTipoObrigatórioDescrição
nomestringSimNome do modo, até 40 caracteres.
itensarraySimItens da loja: [54, 48] ou [{ "id": 6, "preco": 900 }]. Até 40 itens, sem repetir. O preco é opcional (múltiplo de 50, até 12750); sem ele vale o preço do catálogo.
baseintegerNãoModo base de 1 a 5. Padrão 1.
roundsintegerNãoDe 1 a 13. Padrão 13.
moedaintegerNãoMoeda em cada round, de 0 a 999999. Sem este campo vale a do modo base.
curl -X POST "https://guard-salas-api.squareweb.app/api/v1/modes" \
  -H "X-API-Key: SUA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"nome":"So SMG","base":1,"itens":[54,8,{"id":6,"preco":900},102,119],"rounds":7,"moeda":9950}'

Resposta

201 Created
{
  "id": "cm_3f9a1c7b20de",
  "nome": "So SMG",
  "base": 1,
  "rounds": 7,
  "moeda": 9950,
  "itens": [
    {
      "id": 54,
      "name": "UMP",
      "price": 1500
    },
    {
      "id": 8,
      "name": "Mini Uzi",
      "price": 800
    },
    {
      "id": 6,
      "name": "Desert Eagle",
      "price": 900
    },
    {
      "id": 102,
      "name": "Colete Lv.2",
      "price": 400
    },
    {
      "id": 119,
      "name": "Gelo (parede de gel)",
      "price": 300
    }
  ],
  "criado_em": 1789840000
}

Usar o modo em uma sala

curl -X POST "https://guard-salas-api.squareweb.app/api/v1/rooms" \
  -H "X-API-Key: SUA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"modo":"cm_3f9a1c7b20de","nome":"Minha sala","senha":"67"}'

Se também mandar rounds na criação da sala, ele vale só para aquela sala e não pode passar dos rounds do modo. Para listar e apagar: GET /v1/modes (traz os 5 modos e os seus em custom_modes), GET /v1/modes/{id} e DELETE /v1/modes/{id}. Não há limite de modos por key, e só ela vê e usa os seus.

CódigoQuando
400Item inexistente ou repetido, preço inválido, rounds fora de 1 a 13 ou nome vazio.
404Modo customizado não encontrado (ou é de outra key).

Ícones do jogo

GET/v1/iconssem custo

Biblioteca de ícones do jogo (habilidades, pets, buffs e interface). A consulta devolve o nome, a categoria e a URL pública de cada imagem, pronta para usar em embed de bot ou página.

CampoTipoObrigatórioDescrição
qstringNãoBusca pelo nome; todas as palavras precisam aparecer. Ex.: wolf, alok perk.
categorystringNãoskills, pets, buffs ou ui.
largebooleanNãotrue só as versões grandes (_L); false só as normais.
limit / offsetintegerNãoPaginação. limit padrão 100, máximo 500.
curl -X GET "https://guard-salas-api.squareweb.app/api/v1/icons?category=pets&q=wolf" \
  -H "X-API-Key: SUA_KEY"

Resposta

200 OK
{
  "total": 1,
  "limit": 100,
  "offset": 0,
  "icons": [
    {
      "id": "pets/FF_UI_Pet_Wolf_Skill",
      "category": "pets",
      "name": "FF_UI_Pet_Wolf_Skill",
      "key": "wolf",
      "large": false,
      "india": false,
      "bytes": 8123,
      "url": "https://guard-salas-api.squareweb.app/api/icons/pets/FF_UI_Pet_Wolf_Skill.png"
    }
  ]
}

GET /v1/icons/categories lista as categorias com a quantidade de ícones de cada uma.

Baixar a imagem

GET/icons/{categoria}/{arquivo}.pngpúblico

Os arquivos são públicos e não precisam de key, então a url devolvida funciona direto em embed do Discord e em <img>. Ficam em cache por 30 dias.

Conta e modos

GET/v1/accountsem custo

Valida a key e devolve o seu saldo de salas no bot. Com Salas Infinitas, credits vem null e unlimited vem true.

curl -X GET "https://guard-salas-api.squareweb.app/api/v1/account" \
  -H "X-API-Key: SUA_KEY"
200 OK
{
  "api_key_prefix": "fsk_live_ab12",
  "name": "Cliente A",
  "credits": 42,
  "unlimited": false
}
GET/v1/modessem custo
200 OK
{
  "modes": [
    {
      "id": "1",
      "name": "Apostado Sem Carregamento"
    },
    {
      "id": "2",
      "name": "Apostado Com Carregamento"
    }
  ]
}

Exemplo completo

Cria a sala, espera jogadores, expulsa quem entrar de emulador e dá o GO. Repare no Idempotency-Key: se a rede falhar no meio da criação, repetir a chamada com a mesma chave não cria outra sala nem cobra de novo.

const BASE = "https://guard-salas-api.squareweb.app/api";
const KEY = "SUA_KEY";
const api = (method, path, body, extra = {}) =>
  fetch(BASE + path, {
    method,
    headers: { "X-API-Key": KEY, "Content-Type": "application/json", ...extra },
    body: body ? JSON.stringify(body) : undefined
  }).then(async (r) => ({ ok: r.ok, status: r.status, data: await r.json() }));

// 1) cria a sala
const idem = crypto.randomUUID();
const created = await api("POST", "/v1/rooms", { modo: 1, senha: "67", auto_start_min: 5 }, { "Idempotency-Key": idem });
if (!created.ok) throw new Error(created.data.detail);
const { session_id, room_id, password } = created.data;
console.log("Sala", room_id, "senha", password);

// 2) acompanha os jogadores e barra emulador
for (let i = 0; i < 12; i++) {
  await new Promise((r) => setTimeout(r, 5000));
  const { data } = await api("GET", `/v1/rooms/${session_id}/players`);
  for (const p of data.players) {
    if (p.platform === "emulator") await api("POST", `/v1/rooms/${session_id}/kick`, { uid: p.uid });
  }
}

// 3) dá o GO
console.log(await api("POST", `/v1/rooms/${session_id}/start`));

Limites

ItemLimite
Requisições200 a cada 30 segundos por key (e por IP nas rotas sem key, como os ícones). Ao passar disso você fica bloqueado por 1 minuto: todas as chamadas voltam 429 com o header Retry-After. Se achar que foi um engano, entre em contato com um administrador.
Criação de salasAté 10 salas por minuto por conta (exceto keys liberadas pela administração). Acima disso, 429 com Retry-After, sem cobrar.
Tamanho do corpoAté 32 KB por requisição JSON. Acima disso, 413.
MétodosGET, POST e DELETE. Outros métodos voltam 405.
Nome da salaAté 30 caracteres.
SenhaSomente números, até 16 dígitos.
auto_start_minDe 1 a 30 minutos.
Jogadores por sala8.
Esta API não cria sala personalizada (com regras livres). Para trocar modo, nome ou senha de uma sala já criada, use Editar sala (a sala é refeita: o room_id muda).

Erros

Todo erro devolve JSON no formato { "detail": "mensagem" }.

CódigoQuando
400Corpo, senha ou campo inválido, ou JSON malformado.
401Key ausente, inválida ou revogada.
402Saldo de salas insuficiente.
403Acesso à API bloqueado para esta conta. Fale com a administração.
404Sala ou modo não encontrado, ou a sala não é da sua key.
405Método HTTP não permitido.
409A operação conflita com o estado da sala.
413Corpo da requisição grande demais (máximo 32 KB).
429Limite de 200 requisições a cada 30 segundos excedido: bloqueio de 1 minuto. Contate um administrador se for engano.
502Falha ao falar com o jogo. Tente de novo.
503Sem conta disponível agora. Tente em alguns segundos.
Em 429, 502 e 503, repita a chamada depois de alguns segundos com o mesmo Idempotency-Key. Em 400, 401, 402 e 404 repetir não adianta: corrija a causa.