Partner API · v1

The bowling ball catalog,
as an API.

The same normalized catalog behind BowlerDepot Learn: every ball's specs per weight, cover and core, ball motion plotter position and similar-ball suggestions, kept in sync with a cursor-based change feed. Read-only, JSON over HTTPS, built for platforms that need ball data they don't have to maintain.

GET /v1/balls/{id}
$ curl -s -H "Authorization: Bearer $BOWLERIQ_KEY" \
    https://api.bowleriq.io/partner/v1/balls/ff32beb3-…

{
  "name": "PHAZE II", "brand": { "name": "Storm" },
  "coverstock": { "name": "TX-16 Solid", "type": "solid" },
  "core": { "name": "Velocity", "type": "symmetric" },
  "weights": [ { "weight_lbs": 16, "rg": 2.48, "differential": 0.051 }, … ],
  "plotter": { "oil": 9.1, "motion": 14.4, "source": "estimated" },
  …
}
1,800+
balls, current and retired
12
brands, normalized into one schema
1,200+
balls with RG & differential per weight
100%
of current balls on the motion plotter
What's in a ball

One record per colorway, one shape for every brand.

Twelve manufacturers publish specs twelve different ways. The API gives you one schema, with units and vocabularies normalized, and nulls where a manufacturer hasn't published something.

Identity

id · name · brand · color · status · release_date

Stable UUIDs you can key on. Each colorway is its own ball. status is current or retired, and retired balls stay in the catalog.

Specs per weight

weights[ ] · weight_lbs · rg · differential · mass_bias

RG and differential in inches for every weight the manufacturer lists, heaviest first. mass_bias (intermediate differential) for asymmetric cores.

Cover & core

coverstock{ name · material · type } · core{ name · type } · has_particle

Material is reactive_resin, urethane or polyester_plastic; type is solid, pearl or hybrid; cores are symmetric or asymmetric.

Finish

factory_finish · finish_category

The manufacturer's own finish text, plus a normalized category: polished, satin or dull.

Ball motion

plotter{ oil · motion · source }

Where the ball sits on a 16 × 18 oil-versus-motion chart, to 0.1, and whether that came from a manufacturer chart, our model, or a staff correction.

Links & media

image_url · manufacturer_url · learn_article_url · bowlerdepot_url

A CDN-hosted product photo, the manufacturer's page, and BowlerDepot's review and product pages when they exist.

Endpoints

Five endpoints. That's the whole surface.

Every response is JSON with "api_version": "1". Lists page with limit (default 200, max 500) and an opaque next_cursor.

EndpointReturns
GET/v1/changesThe sync feed. Balls created, changed or unpublished since your last cursor, as upsert or remove.
GET/v1/ballsEvery published ball, current and retired, paged by id. For a one-time full load.
GET/v1/balls/{id}One ball by id; 404 if it doesn't exist or isn't published.
GET/v1/brandsBrands with at least one published ball.
GET/v1/plotterEvery current ball's plotter position, plus similar balls from other brands and the nearest step toward more oil, less oil, more angular and smoother.
Staying in sync

Store a cursor. Ask what changed.

You don't re-download the catalog. Call /v1/changes with the cursor you saved last time, apply each upsert or remove by id, save the new cursor, and repeat until has_more is false. The first call with no cursor returns everything.

Changes appear about 60 seconds after they happen. A ball counts as changed when its fields, any weight's specs, its images or its review link change, not on every routine refresh. Each page carries a ball once, in its latest state, and re-applying a page is safe.

Every 15–60 minutes is plenty for most platforms.

sync.py
cursor = load_cursor()          # None on the first run
while True:
    page = get("/v1/changes", cursor=cursor)
    for change in page["items"]:
        if change["change"] == "upsert":
            save(change["ball"])      # create or replace by id
        else:
            delete(change["id"])     # no longer published
    cursor = page["next_cursor"]
    save_cursor(cursor)         # after applying the page
    if not page["has_more"]:
        break
Ball motion plotter

Every current ball on one comparable chart.

Manufacturers publish motion charts on their own scales, if at all. We place every current ball on a single chart: oil from 1.0 (light) to 16.0 (heavy) and motion from 1.0 (smooth) to 18.0 (angular), to a tenth.

Positions read from a manufacturer's published chart are marked chart; the rest come from our model of the cover, finish, core and price (estimated), and staff corrections are manual. /v1/plotter adds the closest equivalents from other brands and the nearest ball in each direction, which is what powers "what should I try next?" features.

oil_scale1.0 light → 16.0 heavy
motion_scale1.0 smooth → 18.0 angular
precision0.1
sourcechart · estimated · manual
twinsclosest balls from other brands
stepsmore_oil · less_oil · more_angular · smoother
Access, limits & versioning

Boring, on purpose.

One key per platform, sent as a bearer token. Keys are issued by us, attributable per partner, and revocable individually. Keep yours server-side.

v1 only grows. We may add optional fields and endpoints, so ignore what you don't recognise. We will never rename, remove or retype a field, or change its units or meaning, inside v1. Anything breaking ships as /v2, and v1 keeps running while you migrate. The v1 contract is locked by automated tests.

base_urlhttps://api.bowleriq.io/partner
authAuthorization: Bearer <key>
formatJSON over HTTPS, read-only
rate_limit~10 req/s, bursts of 20 (429 over)
pagingcursor, 200 default / 500 max
change_lag~60 seconds
schemaOpenAPI 3.1, public
versioning/v1 additive only
Built for

Platforms that need ball data they don't want to maintain.

Drilling & layout software

RG, differential and mass bias per weight, core type and cover for every ball in a customer's bag.

Pro shops & retail

A clean, current catalog with photos and specs, including the retired balls customers still bring in.

Coaching & arsenal apps

Plotter positions and directional steps to explain gaps in an arsenal and what to try next.

Comparison tools

One normalized schema across twelve brands, so a cross-brand comparison is a query, not a project.

Getting started

From email to first sync.

01

Talk to us

Access is by arrangement. Partner keys are issued by BowlerIQ to platforms we work with directly.

02

Get your key

We issue a key for your platform. Paste it into the reference's Try it to make real calls in the browser.

03

Load, then sync

Call /v1/changes once to load everything, then on a schedule with your saved cursor.

Everything else is in the reference.

Every endpoint, field and error, with examples in curl, Python, JavaScript and more, generated from the API itself so it's always current.