Help — clay shooting
Clay shooting API and integration
If the club already runs its own system — an entry site, a members spreadsheet, a results board — the two can talk to each other: the clay shooting API creates the match, sets up rounds and squads, enters athletes and returns the live scoreboard, with nobody retyping anything.
This page is for developers. If you organise the match and are not going to write code, send this page to whoever looks after the club’s system — the rest of the guide is what matters on match day.
Getting started
- In the entity dashboard, the owner opens API keys and creates a key — read only, or read and write.
- Store the secret: it is shown only once. If you lose it, just regenerate the key (the old secret dies immediately).
- Send on every request the header
Authorization: Bearer <access_key>.<secret>. - Call the endpoints below with the prefix
/api/v1/clay.
It is the same key as the IPSC API. A club that already integrates its practical shooting matches needs no new credential for clay shooting.
Scores do not come in through here. The clay strip is signed out in the field: the judge marks clay by clay and signs, the athlete checks it and confirms with the PIN. A score sent over the API would carry neither signature — and that is exactly what guarantees the published scoreboard is what was written on the sheet. The API reads scores; the judge is the one who produces them.
Nor the tie-break. The shoot-off happens with the
field stopped, the judge marks it on the stand and the match office closes it — and its
strip is signed like any other. That is why the API shows the tie-break but does not open,
mark or close it: it is match operation, not integration.
What you can do
- Matches — create, edit, publish and delete. The match starts as a draft already on the modality defaults: the first round (in Skeet, the official 25-target sequence), Squad 1, the rulebook tie-break and the public code.
- Rounds — build the score-sheet layout (stations × clays per station, or the exact station-by-station layout). With no layout in the body, the modality preset is used. The match total is the sum of the active rounds.
- Squads — groups with a schedule and slot limit (default sized by modality: 5 in compak, 6 in trap, skeet and sporting).
- Registration — enter athletes and place them in squads. The athlete joins the same club record that IPSC uses.
- Results — standings with tie-breaks, the clay-by-clay strip, warnings and the state of both signatures.
- Championships — group matches as season legs and read the aggregated ranking, with the minimum legs and the drops already applied.
- Shoot-off — read the field tie-break: who took part, each strip, the placing and how it ended (on the shot, by walkover or by age). Opening, marking and closing belong to the field — see the notice below.
- Categories and classes — build the championship catalog (Senior, Veteran, Ladies, Junior) with the classes of each category and the rulebook brackets. The match returns the catalog in force for it, with inheritance already resolved.
- Public links — entries, results and hub — each one telling you whether it is live and, if not, why.
The module has to be enabled for your organisation. Without that, every route answers 404 — the key is valid, what does not exist is the module for that club. The club switches it on itself, under Club details → Use clay shooting at this club. If the option is not there, the modality is not available in this installation: then it is a case for support.
Example: a full match in four calls
BASE=https://SEU_HOST/api/v1/clay
AUTH="Authorization: Bearer $ACCESS.$SECRET"
# 1. match (starts as a draft, with Round 1 ready)
prova=$(curl -s -X POST $BASE/provas -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"nome": "Etapa COMPAK", "modalidade": "compak", "data_prova": "2026-10-10"}' \
| jq -r .prova.uuid)
# 2. a second round and a squad
curl -s -X POST $BASE/provas/$prova/passadas -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"qtd_postos": 5, "pratos_por_posto": 5}'
squad=$(curl -s -X POST $BASE/provas/$prova/squads -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"limite": 5, "horario_inicio": "09:30"}' | jq -r .squad.uuid)
# 3. entry already in the squad
curl -s -X POST $BASE/provas/$prova/inscricoes -H "$AUTH" -H 'Content-Type: application/json' \
-d "{\"nome\": \"Maria Souza\", \"email\": \"[email protected]\", \"squad_uuid\": \"$squad\"}"
# 4. scoreboard (signed results only; use ?incluir_nao_aprovados=1 for the partial)
curl -s $BASE/provas/$prova/resultados -H "$AUTH"
Championship: catalog and season ranking
The championship owns the catalog: legs inherit from it and the athlete is classified once per season. All of it is optional — with categories and classes off, the entry form keeps the two free-text fields.
# 1. championship with the rules on (comes with the default catalog)
camp=$(curl -s -X POST $BASE/campeonatos -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"nome": "Campeonato 2026", "ano": 2026, "usa_categorias": true,
"usa_classes": true, "minimo_etapas": 3, "descartes": 1}' | jq -r .campeonato.uuid)
# 2. the match becomes a leg and starts inheriting the catalog
curl -s -X PUT $BASE/provas/$prova/campeonato -H "$AUTH" -H 'Content-Type: application/json' \
-d "{\"campeonato_uuid\": \"$camp\"}"
# 3. the catalog in force for THIS match (scope: championship, match or club)
curl -s $BASE/provas/$prova/catalogo -H "$AUTH"
# 4. season ranking, with drops and minimum already applied
curl -s $BASE/campeonatos/$camp/ranking -H "$AUTH"
The class bracket is half-open:
valor_min is included and valor_max is not. That is what keeps "AA from 87 to 94" and "Premium 94 upwards" from overlapping. The faixa field comes ready to display — "26–35" in clays, "≥87 and <94" in percentage.
Interactive reference
Explore and try the endpoints below (Swagger UI). The OpenAPI specification JSON is at openapi.json.