---
name: handballapi
description: Handball results and history from handballapi.com. Use when an agent needs finished handball match results, half-time scores, venues, crowds, referees or player and goalkeeper lines for national leagues, international events or past seasons.
---

# Handball API

Handball results and history as a REST API and an MCP server, operated by DeveloperData.net. Matches are served once they are over: finished or awarded results, with half-time, venue, crowd, referees and player lines (goals, shots, 7m, assists, cards, saves).

## When to use it

- Use it for results: what happened in a match, on a day, in the last few days, and who scored or saved what.
- Do not use it for live scores, in-play data, betting prices, predictions or tips: it has none of these on any plan.
- Some competitions are never covered because their data rights are held by an official data partner: Handball-Bundesliga, EHF competitions, Superliga (Poland), the Austrian leagues and Liga ASOBAL. Say so rather than searching elsewhere in the API.

## Getting access

- Sign up at https://handballapi.com for a free key. The free key reaches yesterday's and today's results.
- Send the key in a header: `Authorization: Bearer <key>` or `X-API-Key: <key>`. Never in the address: that is refused.
- Base URL: `https://api.handballapi.com/v1`. All times are UTC.

## The calls

Results finished yesterday (UTC), optionally for one country:

```bash
curl -H "Authorization: Bearer $KEY" "https://api.handballapi.com/v1/results/yesterday?country=si"
```

```json
{"data": [{"id": "mt_8kq2v7xd", "date_utc": "2026-10-06T18:00:00Z", "status": "finished",
  "competition": {"id": "cp_3m9t1bra", "name": "Liga NLB", "country": "si", "season": "2026/27"},
  "home": {"team_id": "tm_5h2c8wqe", "name": "RK Celje", "goals": 31, "ht": 15},
  "away": {"team_id": "tm_0d7r4kna", "name": "RD Riko Ribnica", "goals": 27, "ht": 13}}],
 "meta": {"count": 1, "next_cursor": null, "page": 1, "per_page": 100, "total": 1, "total_pages": 1}}
```

The ids above show the shape only; use ids from a real answer. Ids are permanent: `mt_` matches, `tm_` teams, `cp_` competitions, `pl_` players, `rf_` referees, `vn_` venues.
Every match also carries `kickoff_local` (the league's own time, with its offset) and `timezone`, both null for international rows or where only the date is published.

- `GET /v1/results/latest?days=2`: finished in the last 1 to 7 days.
- `GET /v1/results?date=YYYY-MM-DD`: every result on one UTC day.
- `GET /v1/matches/{id}`: one match, adding `venue`, `attendance`, `referees`, `shootout`, `discipline` (indoor, beach, wheelchair) and `player_lines`.
- `GET /v1/matches/{id}/players?team=home`: player lines; goalkeepers carry `saves`, `shots_faced` and `save_rate`.
- `GET /v1/fixtures?days=7`: matches scheduled in the next 1 to 14 days, soonest first.
- `GET /v1/competitions/{id}/table?season=2025/26`: a league table computed from the results held (2 points a win, 1 a draw).
- `GET /v1/competitions/{id}/scorers?season=2025/26`: top scorers from the player lines held.
- `GET /v1/teams/{id}/head-to-head?opponent={id}`: every meeting of two teams, with a won, drawn, lost and goals summary.
- `GET /v1/competitions?country=de`, `GET /v1/teams?q=kiel`, `GET /v1/players?q=hansen`, `GET /v1/referees?q=nygaard`, `GET /v1/venues?q=arena`: find ids by name or country.
- `GET /v1/competitions/{id}/seasons`, `/home-away`, `/form`, `/goalkeepers`, `/discipline`, `/stats`, `/records`: a competition's seasons, tables, leaders and figures (all take `season`).
- `GET /v1/teams/{id}/results`, `/fixtures`, `/squad`, `/stats`, `/form`, `/streaks`: one team's matches, players, figures and runs.
- `GET /v1/players/{id}/career` and `GET /v1/players/leaders?stat=goals&season=2025/26`: a player's totals, and the season's leaders.
- `GET /v1/matches/{id}/officials` and `GET /v1/referees/{id}/stats`: a match's referees, and a referee's record.
- `GET /v1/matches?team={id}&from=YYYY-MM-DD`: matches by team, competition, season and dates.
- `GET /v1/updates?since=<UTC time>`: every match added or changed since then (up to 7 days), to keep a copy in step.
- `GET /v1/meta/coverage`: what is held, counted by country, and what is never collected.
- `GET /v1/usage`: this key's plan, calls today, limits and reach. Not counted.

`country` takes: dk, se, si, hr, cz, tr, gr, br, de, sk, rs, es, ch, ihf, history.

## MCP

Server: `https://handballapi.com/mcp` (HTTP POST, JSON-RPC 2.0), with the key in `Authorization: Bearer <key>`.
Each tool calls one endpoint above, on the key's plan. Call `tools/list` for their arguments.
Tools: `yesterdays_results`, `latest_results`, `results_on_day`, `get_match`, `match_players`, `fixtures`, `league_table`, `top_scorers`, `head_to_head`, `coverage`, `find_competitions`, `find_teams`, `find_players`, `find_referees`, `search_matches`, `match_officials`, `competition_seasons`, `home_away_table`, `league_form`, `top_goalkeepers`, `season_stats`, `team_results`, `team_fixtures`, `team_stats`, `team_form`, `team_squad`, `player_career`, `player_leaders`, `referee_stats`, `home_advantage`.

## Limits

- Free key: yesterday and today only, no player lines or compiled season figures; searching for competitions, teams, players and referees works on every plan.
- Paid plans reach further back and allow more calls; `GET /v1/usage` gives this key's exact limits.
- Every answer carries `X-RateLimit-Remaining` and `X-Quota-Remaining`. Lists page with `per_page` (up to 200) and `page` or `cursor`.

## Errors

Every error is `{"error": {"code", "message", "plan"?, "docs"}}`.

- 400 `bad_request`: a wrong value; the message says what was expected.
- 401 `unauthorized`: no key, or not valid.
- 403 `upgrade_required`: past the plan's reach; `plan` names the plan that has it.
- 404 `not_found`: no endpoint, or no finished match with that id.
- 422 `unknown_parameter`: the message lists the parameters the endpoint takes.
- 429 `rate_limited` or `quota_exceeded`: wait `Retry-After` seconds.

## A typical workflow

1. Call `GET /v1/usage` once to learn the plan and how far back it reaches.
2. Find matches with `results/yesterday`, `results/latest` or `results?date=`, filtered by `country`.
3. Take a match `id` and call `matches/{id}` for the details, then `matches/{id}/players` for scorers and goalkeepers.
4. On `upgrade_required`, tell the user which plan has it instead of retrying. On `429`, wait `Retry-After` seconds.
5. If a competition is missing, check `meta/coverage` and its `not_collected` list before concluding there is no data.
