Skip to content
British Powerlifting — Tools Portal home

Developer

Competition data feeds

Read-only JSON feeds of the national championships run through this portal. No authentication or API key needed.

All data feeds & APIs → · Download as Markdown for AI tools · Terms of use

Overview

Two feeds: an index of every publicly listed competition, and one feed per competition. Start from the index — each competition in it carries the address of its own feed, so you never need to know or build competition addresses yourself.

The feeds hold the same information as the public competition pages — nothing more. A section appears only when that competition publishes it on its page; if it isn't on the page, it isn't in the feed. Contact details, dates of birth, membership numbers and payment status are never included.

Responses are application/json, UTF-8, and indented so they read in a browser. Dates are ISO 8601 (2026-12-04); times without a zone are UK local time. Weights are kilograms.

Versioning. These are version 1 of the API (/api/v1/). Within v1 we only add fields, never remove or rename them, so ignore keys you don't recognise. The old addresses (/competitions/feed.json and /competitions/{slug}/feed.json) still work but are deprecated.

Fair use: the index and the per-competition feeds are each limited to 120 requests per hour per IP address (every competition's feed shares that one count), and responses may be cached for 5 minutes, so polling more often than that gains nothing. Over the limit you get HTTP 429 with a JSON body and a Retry-After header. The feeds can be fetched from a web page on another site (CORS is open).
GET /api/v1/competitions

Every publicly listed competition, split into current (entries open first, then soonest) and past (most recent first) — the same order as the competitions page.

Example request

curl https://tools.britishpowerlifting.org/api/v1/competitions

Response shape

{
  "competitions_url": "https://tools.britishpowerlifting.org/competitions/",
  "current": [
    {
      "name": "SBD British Open Championships",
      "slug": "british-open-2026",
      "state": "open",
      "state_label": "Entries open",
      "entries_open": true,
      "event_start_date": "2026-12-04",
      "event_end_date": "2026-12-06",
      "venue": "NEC Birmingham",
      "equipment": "classic",
      "discipline": "full_power",
      "page_url": "https://tools.britishpowerlifting.org/competitions/british-open-2026",
      "feed_url": "https://tools.britishpowerlifting.org/api/v1/competitions/british-open-2026"
    }
  ],
  "past": [ /* same shape */ ]
}

state is one of open, soon, upcoming, offers, closed or completed; state_label is the wording the page shows.

GET /api/v1/competitions/{slug}

Everything the public page for one competition shows. Use the feed_url from the index rather than building this yourself. An unknown or unlisted competition returns 404 with {"error": "not_found", ...}; a renamed one redirects (301) from its old address, so follow redirects.

Example request

curl https://tools.britishpowerlifting.org/api/v1/competitions/british-open-2026

Sections

Key Present when
competition Always. Name, dates, venue, fees, stage, whether entries are open, and links back to the page, this feed and the index.
qualifying_totals Always. One row per weight class. qualifying_total_kg is null where entry is by classification (Special Olympics). availability appears when the competition shows place availability.
key_dates When the page shows its Key dates card.
nominations When the competition publishes its confirmed nominations list.
live_entries When the competition publishes its live entry list — everyone still in the running, by class, best total first.
standby With the live entry list: athletes outside their class's places, ranked on GoodLift points within their pool — the order a freed place is redistributed in.

Response shape (abridged)

{
  "competition": {
    "name": "SBD British Open Championships",
    "slug": "british-open-2026",
    "venue": "NEC Birmingham",
    "event_start_date": "2026-12-04",
    "event_end_date": "2026-12-06",
    "entry_fee_gbp": 120.0,
    "entry_fees_by_category": { "open": 120.0 },
    "stage": "eoi_open",
    "entries_open": true,
    "entries_close_at": "2026-11-01T23:59:00",
    "page_url": "...", "feed_url": "...", "all_competitions_feed_url": "..."
  },
  "qualifying_totals": [
    { "sex": "F", "age_category": "open", "class": "-63", "qualifying_total_kg": 412.5 }
  ],
  "key_dates": [
    { "key": "entries_close", "label": "Entries close", "date": "2026-11-01", "detail": "..." }
  ],
  "nominations": [
    { "rank": 1, "name": "Alex Example", "listed_by_initials": false, "region": "Yorkshire",
      "sex": "F", "weight_class": "-63", "age_category": "open", "total_kg": 465.0,
      "day": 1, "flight": "A" }
  ],
  "live_entries": [
    {
      "position": 1,
      "name": "Alex Example",
      "listed_by_initials": false,
      "sex": "F", "weight_class": "-63", "age_category": "open",
      "places": 16, "in_places": true,
      "status": "confirmed", "status_label": "Place confirmed", "place_confirmed": true,
      "total_kg": 465.0, "total_verified": true,
      // profile extras — see below
      "statement": "Here to total big",
      "job_title": "Physiotherapist",
      "socials": [ { "platform": "instagram", "label": "Instagram", "url": "...", "handle": "@alex" } ],
      "portrait_url": ".../lifter/AbC123/portrait.jpg?v=20261001120000",
      "portrait_square_url": ".../lifter/AbC123/portrait.jpg?variant=square&v=20261001120000",
      "profile_url": ".../lifter/AbC123"
    }
  ],
  "standby": [
    { "pool": "open-F", "pool_label": "Women", "position": 1, "name": "...",
      "weight_class": "-72", "status": "registered", "status_label": "Registered",
      "gl_points": 81.42, "bodyweight_needed": false }
  ]
}

Notes

  • No ages. age_category on a row is the pool the athlete contests (e.g. open), not their own age band — the feeds never say how old anyone is.
  • Athlete status. status is confirmed, offer_out, registered or reserve. “Confirmed” means the place is final, however it was finalised — the feed never says who has or hasn't paid.
  • Profile extras (quote, job title, socials, photo and profile links) appear only for athletes whose place is confirmed and who are listed by full name, and only when the competition shows profiles. Athletes listed by initials — including every under-18 — never have a photo, quote or profile link. Treat any of these keys as optional.
  • Photos. portrait_url is a 4:5 portrait, portrait_square_url a 1:1 crop for avatars. The v= part changes whenever the photo is replaced, so a URL can be cached as long as you like. Link to them rather than copying the image: a photo stops being served the moment an athlete is withdrawn or asks to be listed by initials.
  • Totals are as declared until total_verified is true, and can change before then. in_places is today's standing, not a promise of a place.
  • Missing values are null or the key is left out — code defensively, and expect new keys to be added over time.