Setting up the api

Create an <iframe> with the following source, make the iframe invisible. This url is loaded once when your page opens, and it sits there listening for requests. Since there is no further web trafic, the calculations will happen very quickly.

The api development is still in progress, develop and test your site using this test url. Not recommended for use on a live site. When it's ready, this url will be updated.

Sending requests to the api

The api is controlled using JavaScript postMessage() to send requests to the <iframe>.


apiLocation.postMessage(message, "*");

message : This is a javascript object with the following format:

  parameter1 : value1,
  parameter2 : value2,
  parameter3 : value3,

Do not use JSON.stringify() on the object. Just create an object and send it.

All parameters are case sensitive.

Parameter values are numeric, except where shown.

Do not url encode any values.

Spoke length calculations

Hub parameters
type0=Normal hub 1=Straight pull hub
frontRear0=Front 1=Rear
pcdLPitch diameter Left
pcdRPitch diameter Right
flangeLFlange offset Left
flangeRFlange offset Right
holeDiaSpoke hole diameter. Only required for normal (type 0) hubs*
spOffsetLStraightpull offset Left. Only required for straightpull (type 1) hubs*
spOffsetRStraightpull offset Right. Only required for straightpull (type 1) hubs*
Rim parameters
erdRim erd
asymAsymmetric offset. For non asym rims use a value of 0.
rimHoleWidthHole width, see the calculator help guide for a description of this (Width between holes).
Wheel lacing
frameOffsetFrame offset dimension. Optional. Only required if the wheel is being built for an offset frame. Valid entries are 0, 1, 2, 3, 4, 5, 6, 7, 8, 17.5, 28. The last two entries will peform a fatbike calculation for a rim with a double row of spoke holes.
spokesSpokes in the wheel. Valid entries are 16, 20, 24, 28, 32, 36, 40, 48
spokeDiaLSpoke diameter Left. Valid entries are 1.4, 1.5, 1.6, 1.7, 1.8, 2, 2.3
spokeDiaRSpoke diameter Right. Valid entries as above.
crossLLacing pattern. Cross Left. Valid entries are 0, 1, 2, 3, 4
crossRLacing pattern. Cross Right.Valid entries as above.
Optional **
hubNameHub name
rimNameRim name
spokeNameLSpoke name Left
spokeNameRSpoke name Right
Optional (other)
calculationIDA unique ID for the calculation. Whatever you set here will be returned with the calculation.

*If you send holeDia for a straightpull hub or spOffset values for a normal hub, they will be ignored.

**Any values you set will be included in the wheelSummary return property (see below). The values are plain text without html formatting tags, and do not url encode them.

Spoke selection

This calculator takes into account spoke elongation and requires a spoke diameter (spokeDiaL, spokeDiaR). You must allow the user to select the correct diameter spoke.

The simple way is to provide a drop down list of diameters (as used on the Wheelpro website calculator), but remember that some users will still select 2mm diameter for a Sapim CX-Ray and get less than perfect spoke lengths (these are the users who do not read the help guide for spoke diameter).

An alternative is to show a list of specific spoke types, for example <option value="1.5">DT Revolution</option>.

Error checks

The api will check that all the required fields are sent for the particular wheel. If you send data that is not applicable, then it will be ignored.

The api will then perform the same validation rules from the standard calculator (the non api version on the Wheelpro website), and show errors and warnings where necessary. It will not check for incorrect values such as an erd of 9999.

Return values

The API will post an object back to your page. You must set a message listener on your page, with a function that handles the return values.

When the calculator api first loads, it will send a message to inform you that it's ready. Prior to this, you should disable your calculator from sending requests (because the api is not ready to receive them).

window.addEventListener("message", apiMessageReceiver);

function apiMessageReceiver(api) {
    if ( {
        // Enable your calculator.
    else { // Spoke calculation.
        if ( { // Something wrong with the data that was sent.
   // This value contains an error message
                                  // that you should display somewhere.
        else { // Successful calculation.
            // See below for the return values.

Return values for a spoke length calculation

spokeLengthsA table with the left and right spoke lengths.
spokeLengthsExtraA table with spoke lengths, plus additional information (tension ratio etc.)
    <tr><th>Heading 1<td>value<td>value
    <tr><th>Heading 2<td>value<td>value
calculationNotesParagraph formatted wheelbuilding notes that are applicable to the calculation. You should always display these notes. Warning notes are preceded with:
<span class="warning">Warning</span>
wheelDataA table containing all the data used in the calculation (some value columns can be combined).
  <tr><th>Heading 1<td>value<td>value
  <tr><th>Heading 2<td>value<td>value
  <tr><th>Heading 3<td colspan="2">value
calculationLogStuff for spoke length nerds! Contains the following tags:
<h1> <h2> <ul> <li>
wheelSummaryPlain text basic summary of the wheel set to either Front wheel, Rear wheel, Straight pull front wheel or Straight pull rear wheel.
wheelSummaryExtraA summary of the wheel component names presented in a table. The table only includes names sent in the calculation request. If spokeNameL is the same as spokeNameR then only one entry will be shown. See the developer notes below.
  <tr><td colspan="2">Wheel summary (see above)
  <tr><td>Left<td>Left spoke name
  <tr><td>Right<td>Right spoke name
wheelSummaryExtra is currently not available, still thinking about this one. You can of course create this yourself, since you have all the informtion your side. Comments appreciated.

The first thing your processing should do, is check the value of error. If error==true, then errorMessage contains the actual error. Errors are caused by bad data such as wrong values, missing values, or data that would create an impossible wheel (for example a hub diameter larger than the rim). If an error is set, then all the above parameter values will not be defined, except for the calculationLog which may contain more detail on the source of the error.
calculationIDReturning the same value you sent with the calculation data, or false if you didn't send one.

Additional requests

userGuidePost this value to the api and it will return a user guide for end users of the calculator. Typically you would call this once at your calculator startup, then display it via a menu or other link for your users to access. You'll need to modify the above example code for apiMessageReceiver to handle a return value for the userGuide property. If you don't want a full user guide, then the minimum you must say, is round the spoke lengths up.

Developer notes

When developing your calculator page, the following will be useful.

The api sits in an invisible iframe, but instead of firing off test posts into a black hole, open up the frame and give it some height and width, and you'll see the actual calculator and be able to see where your values are going, and how the calculator handles them.

You can also enter values into the calculator, and when you click Calculate it will fire off the results to your own web page. This is good for testing, because you can easily try all sorts of test data and see how your page handles it without having to edit your hub/rim database with rogue values.

Opening up the iframe will temporarily alter your page layout, so an alternative technique is to open the api in a new window. Take a look at the page source for the example, to see how I did it. Most browsers will open the window in a new tab, but just detatch the tab into a genuine window, and arrange things so your calculator page and api window are side by side.


Make sure your data entry form always matches whatever spoke length calculation is displayed. You don't want users to change any form value without a re calculation being done, otherwise they may read off spoke lengths that are not applicable to their choice of components. A couple of ideas to keep things in sync:

1. As soon as a form entry changes, refresh your display with a new calculation. That's what I do in the example. Doing it this way does not require a calculate button.

2. If you use a calculate button, then when a form entry changes, clear the display.

I also recommend you show the wheelSummary. It gives confidence to the user that their clicks got through! It also acts as a reminder of the actual components they chose, and may highlight an error, for example they may have wanted a rear wheel calculation, and mistakenly selected a front hub - the wheelSummary should alert them.