Ajuda — tiro de precisão
API e integração do tiro de precisão
A API pública do tiro de precisão permite que o sistema do seu clube crie provas, inscreva atletas e leia o resultado sem ninguém redigitar nada.
A chave
É a mesma chave dos outros módulos. O dono do clube cria em Entidade → Chaves de API; a secret aparece uma única vez, na criação. Guarde-a com o cuidado de uma senha.
Authorization: Bearer <access_key>.<secret>
- Escopo "leitura" permite só GET; "leitura e escrita" libera o resto.
- Tudo é escopado ao seu clube. Não existe requisição que alcance dado de outra entidade.
- Se o módulo não estiver habilitado para o clube, a resposta é 404 — a chave é válida, o recurso é que não existe para você.
Os três eixos da prova
Entender isto antes de integrar economiza a maior parte do retrabalho:
- Modalidade — o percurso de fogo. No cadastro do clube é reutilizável; dentro da prova é uma CÓPIA. Editar o cadastro depois não muda prova montada — é o que garante que resultado de prova encerrada nunca mude. É a ela que a inscrição aponta e por ela que o ranking agrupa.
- Série — o eixo de tempo: a rodada.
- Turno — o eixo de espaço: quem atira junto, com limite de vagas.
Um dia de prova, em quatro chamadas
BASE=https://seu-dominio/api/v1
AUTH="Authorization: Bearer $ACCESS.$SECRET"
# 1. criar a prova já com as modalidades do cadastro do clube
curl -s -X POST $BASE/precisao/provas -H "$AUTH" \
-H 'Content-Type: application/json' \
-d '{"nome":"1ª Etapa 2026","data_prova":"2026-03-14",
"modalidades":["<uuid-da-modalidade>"],
"external_id":"etapa-1-2026"}'
# 2. inscrever um atleta numa modalidade e num turno
curl -s -X POST $BASE/precisao/provas/$prova/inscricoes -H "$AUTH" \
-H 'Content-Type: application/json' \
-d '{"prova_modalidade_uuid":"<uuid>","turno_uuid":"<uuid>",
"nome":"Fulano","email":"[email protected]",
"sexo":"M","data_nascimento":"1988-04-02",
"external_id":"insc-4471"}'
# 3. abrir a prova e publicar os resultados
curl -s -X PATCH $BASE/precisao/provas/$prova -H "$AUTH" \
-H 'Content-Type: application/json' \
-d '{"status":"aberta","resultados_publicos":true}'
# 4. ler o ranking (agrupado por modalidade, com o desempate aberto)
curl -s $BASE/precisao/provas/$prova/resultados -H "$AUTH"
external_id: o id do SEU sistema
Todo recurso de prova e de inscrição aceita um external_id. Grave nele o id do registro do seu lado e você reencontra tudo sem precisar guardar os nossos uuid:
curl -s "$BASE/precisao/provas?external_id=etapa-1-2026" -H "$AUTH"
Ele é único no escopo (clube para provas, prova para inscrições), o que o torna também uma chave de idempotência: reenviar o mesmo POST devolve conflito em vez de criar um duplicado silencioso. Enviar null desvincula; omitir o campo não mexe no que está gravado.
Score não se escreve por aqui
Pelo mesmo motivo, a API nunca emite nem devolve o PIN de um atleta. Existe só o caminho de apagá-lo, para que o atleta crie outro — o PIN é segredo dele, e um integrador que o conhecesse esvaziaria o sentido da assinatura do atleta.
O que trava, e por quê
Estas regras valem igual na tela e na API. Todas devolvem 409:
| Tentativa | Por quê |
|---|---|
| Mudar desempate ou exigência de PIN com score lançado | As duas fazem parte do que foi assinado; mudá-las reordenaria o ranking sem ninguém atirar. |
| Mudar o percurso da modalidade com score lançado | A fita assinada aponta para aqueles alvos. |
| Renumerar série com score lançado | O desempate por série final lê as séries pela ordem. |
| Trocar a modalidade de uma inscrição com score | Moveria uma fita assinada para outro percurso de fogo. |
| Excluir inscrição com score | Sobraria fita assinada sem dono. Use status "cancelada". |
| Publicar prova em rascunho | A estrutura ainda vai mudar; o link mostraria algo que não se confirma. |
| Alterar estrutura de prova encerrada | O resultado já circulou como oficial. |
| Passar do limite de vagas do turno | É o mesmo limite que a tela respeita. |
Excluir uma prova exige, além disso, o nome exato dela em ?confirmacao= — a mesma zona de perigo da interface.
Paginação, limites e erros
- Listagens aceitam ?page (a partir de 1) e ?per_page (padrão 25, máximo 100; nas inscrições, padrão 50 e máximo 200) e devolvem page, per_page e total.
- Rate limit por chave, com os headers X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset. Excedido devolve 429 com Retry-After — respeite-o em vez de repetir em loop.
- Erro é sempre JSON no mesmo formato: {"error": {"code": "not_found", "message": "Prova não encontrada."}}. A mensagem é escrita para ser lida por quem está integrando, não só registrada.
Conferir o que a integração fez
Cada prova expõe a própria trilha de auditoria, e as ações feitas por chave aparecem nela junto com as feitas na tela. É como se reconcilia o que o robô fez com o que a secretaria fez:
curl -s "$BASE/precisao/provas/$prova/auditoria?acao=precisao.prova_update" -H "$AUTH"
Referência interativa
Explore e teste os endpoints abaixo (Swagger UI). O JSON da especificação OpenAPI está em openapi.json.