LIGR Studio goes live in --d --:--:--→LIGR Studio is liveStart free trial →
Blog and news/Guide17 Oct 2026·8 min read

Live Score API: Score a Match From Your System

Connect your scoring system to LIGR: create the match, set the lineup, post a fact for each goal or card, fix mistakes and read back the summary.

Developer guide

Your scoring system stays the source of truth. LIGR takes one fact per event and turns it into the score, the clock, the statistics and every graphic that reads them.

To score a LIGR match from your own system, create the match with POST /v2/matches, set the lineup, then post one fact for every event to POST /v2/matches/{matchId}/facts. LIGR computes the score, the clock, the statistics and the graphics from those facts. Correct a fact by updating or deleting it, and read the result back from the match summary. This guide follows Score a match from your system in the LIGR developer docs, which walks one football match with curl.

Who this is for

Leagues, federations and data teams that already capture match events, in a scoring app, a stats system or a results database, and want LIGR graphics and highlights to follow them. You need a write key with matches:write for the match, the lineup and the facts, plus teams:write if you add players to a roster. The REST API quick start covers keys and scopes.

What you can build

SportWhat you buildWhat the docs give you
FootballA pitchside or press-box scoring app that posts goals, cards and substitutions as they happenThe full fact name list, the periods and the error messages
TennisA tournament system that creates singles and doubles matches, with player competitors in place of teamscompetitorsType of singles or doubles, and entityType: player rows
AFLA team-sheet tool that sends each side's starters and bench before the first bouncePUT /v2/matches/{matchId}/lineup, which open overlays show at once
Basketball, netball, American footballA stats system that posts its events as facts and reconciles against the summary after every gameThe same endpoints. Fact name references for these sports are marked coming soon, so ask your LIGR contact for the names

The fact endpoint does not check name against a list. A name LIGR does not know is stored and drives nothing: no score, no statistic and no graphic. That is why the sport-specific names matter.

How it works: one football match

1

Find the ids you need

A match belongs to a competition, takes place at a venue and has two teams. Read them once with GET /v1/competitions, GET /v1/competitions/{competitionId}/teams and GET /v1/venues, and keep the ids.

2

Create the match

Send POST /v2/matches with the competition, the venue, the kick-off date in ISO 8601 with its timezone, competitorsType and a competitors array. Each competitor row has an entityId, an entityType and meta.isHome. Keep the id in the answer.

3

Set the lineup

Send the starters and the bench of each team to PUT /v2/matches/{matchId}/lineup. Graphics use the lineup to show the teams, list the scorers and fill the player variables. Each player must be on the team roster: add a missing one with POST /v1/teams/{teamId}/players, and set shorter graphics names with gfxFirstName and gfxLastName. The call replaces the lineup of each team you send.

4

Start the first half

Post a PERIOD_STARTED fact with periodNumber: 1. The match goes live and the clock starts. Periods start in order: a PERIOD_STARTED that skips a period returns 400.

5

Post each event as a fact

name is the event, periodNumber is the period it happened in, teamId and playerId say who, and data carries the sport-specific detail. This goal is copied from the docs guide:

curl -X POST 'https://api.ligr.live/rest/v2/matches/1188213/facts' \
  -H "Authorization: Bearer $LIGR_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{ "name": "GOAL", "periodNumber": 1, "teamId": 1, "playerId": 501, "data": { "shotOnTarget": true } }'

The answer carries the fact id. Keep it: you need it to correct or delete the fact. date defaults to the time LIGR receives the fact. Send it when your system timestamps the event, because LIGR derives the match minute from date and the period start.

6

Correct a mistake

Update a fact with POST /v2/matches/{matchId}/facts/{factId}, sending only the fields that change, for example a new playerId. Delete a fact that never happened with DELETE on the same path. LIGR recomputes the score and the statistics. A period fact can be deleted only while it is the most recent one.

7

Close the match and read it back

Post PERIOD_FINISHED for the last period. To end a match early, call POST /v2/matches/{matchId}/finish. To cancel or abandon it, call …/cancel or …/abandon. Then read GET /v2/matches/{matchId}/summary, the score, periods, clock and statistics LIGR folded from your facts, and compare it with your own state.

Football periods and fact names

A football match runs through periods 0 pre-match, 1 first half, 2 half time, 3 second half and 4 full time. PERIOD_FINISHED with 1 stops the clock and moves the match into half time, and PERIOD_STARTED with 3 starts the second half. The most used fact names:

nameEvent
GOAL, OWN_GOAL, PENALTY_SCOREDA goal. An own goal counts for the other team
YELLOW_CARD, SECOND_YELLOW_CARD, RED_CARDA card for teamId and playerId
SUBSTITUTIONCounts in substitutions. Optional data { "off": 501, "on": 502 } swaps the players in the lineup
CORNER_WON, OFFSIDE, SAVEA corner, an offside or a save
SHOT_ON_TARGET, SHOT_OFF_TARGET, SHOT_BLOCKEDA shot
FREE_KICK_CONCEDED, PENALTY_CONCEDEDFouls. FOUL on its own does not change fouls
CLOCK_STOPPED, CLOCK_STARTEDStop or start the clock inside a period
SHOOTOUT_GOAL, SHOOTOUT_MISSA penalty shootout attempt

Possession, passes, tackles and other Opta-only statistics come only from a data provider feed. No fact sets them. The full table is in the scoring guide, and the request shape is on Create a fact.

Keep LIGR in step with your system

  • Post every fact once. LIGR does not deduplicate facts. Make a retry safe: read the match back before you post again.
  • Post in the order things happened. The summary is folded in fact order.
  • Confirm with webhooks. Subscribe a webhook to fact and summary events to see what LIGR computed, as it computes it. See sports webhooks.
ErrorCause
400 Could not find period 'N'periodNumber is not a period of this match
400 Period has already startedA second PERIOD_STARTED for the current period
400 Invalid lineupA player is not on the roster, or a team does not play in the match. details names each bad value
404 No fact found with id 'N'The fact does not belong to the match in the path

Other sports. The fact endpoint is the same for every sport, and only the fact names change. The docs mark the fact name references for tennis, basketball, Australian rules, rugby league, rugby union, cricket, netball and the other sports as coming soon. Until they are published, ask your LIGR contact for the names. GET /v2/schemas/sports/{sport} returns the data shape graphics read for each sport.

Frequently asked questions

How do I send live scores to LIGR from my own system?

Create the match with POST /v2/matches, set the lineup with PUT /v2/matches/{matchId}/lineup, then post one fact per event to POST /v2/matches/{matchId}/facts with a matches:write key. LIGR computes the score, the clock, the statistics and the graphics from the facts.

Does LIGR deduplicate facts?

No. Post every fact once, in the order it happened, because LIGR folds the summary in fact order. Keep the id of every fact you post, so you can correct or delete it.

How do I fix a wrong goal scorer or a disallowed goal?

Update the fact with POST /v2/matches/{matchId}/facts/{factId}, sending only the fields that change, such as playerId. Delete a fact that never happened with DELETE on the same path. LIGR recomputes the score and the statistics.

Which sports can I score through the LIGR API?

The fact endpoint is the same for every sport, and only the fact names change. Football has a full fact name reference in the docs. For other sports, including tennis, basketball, Australian rules, netball and American football, the references are marked coming soon, so ask your LIGR contact for the fact names.

How do I check what LIGR computed?

Read GET /v2/matches/{matchId}/summary, which returns the score, the periods, the clock and the statistics, and compare it with your own state after every match. A webhook subscribed to fact and summary events confirms each change as it happens.

Connect your scoring system

The scoring guide walks a full football match with curl, with every fact name, period and error message.

Related reading

Related posts