![]() |
![]() |
![]() |
This article explains the JSON file format used by the Spinfire app for exporting and importing custom tennis drills. Understanding this format can be helpful for sharing drills or for advanced users who might need to inspect or manually edit drill data.
What is a Drill JSON File?
When you export a drill from the Spinfire app, the information about the drill’s sequence of shots, settings, and other properties is saved in a JSON (JavaScript Object Notation) file. This file is a structured text format that can be easily read by computer systems and, with a little understanding, by humans.
JSON Format Versions
There are two main versions of the JSON format used by the Spinfire app:
1. Older Version (Version 1): This format is more compact but less intuitive for manual reading or editing. Shots are represented as a list of numbers.
[{"id":22,"name":"Drill 22","shots":[[16,12,4,53,0,6],[16,12,4,53,74,10]]}]
This format can be difficult to interpret manually.
2. Current Version (Version 2): This format is designed to be easier to read and understand, especially if you are looking at the file contents. Each shot is represented as an object with clearly named properties.
[
{
"id": 22,
"name": "Drill 22",
"shots": [
{
"interval": 16,
"speed": 12,
"spin": 4,
"elevation": 53,
"horizontal": -37,
"courtPositionId": 6
},
{
"interval": 16,
"speed": 12,
"spin": 4,
"elevation": 53,
"horizontal": 37,
"courtPositionId": 10
}
],
"version": 2,
"sortOrder": 0,
"notes": "",
"imagePath": "",
"videoUrl": ""
}
]
This article focuses on Version 2, as it is the current standard and easier to understand.
Compatibility: The most recent version of the Spinfire app (e.g., Version 1.1.6 or later) can import both Version 1 and Version 2 JSON files. Older app versions may only support Version 1. Ensure you and anyone you share drills with are using the latest app version.
Understanding JSON Version 2 Structure
The Version 2 JSON file is a list ([]
) of one or more drill objects ({}
). Each drill object contains the following key information:
- id: A unique identifier for the drill (usually assigned by the app).
- name: The name of the drill (e.g., “Drill 22”, “Test 200”).
- shots: This is a list (
[]
) containing one or more shot objects ({}
). Each object defines the settings for a single shot in the drill sequence. - version: Indicates the JSON format version (should be
2
for this format). - sortOrder: Used by the app to manage the order of drills.
- notes: Any text notes saved with the drill.
- imagePath: (Optional) Path to an associated image.
- videoUrl: (Optional) URL for an associated video.
Understanding Shot Properties (Within the shots
list)
Each object within the shots
list defines a specific shot with parameters like:
- interval: Time delay before this shot fires.
- speed: Ball speed setting.
- spin: Ball spin setting.
- elevation: The intended vertical angle setting. (See important note below)
- horizontal: The intended horizontal setting.
- courtPositionId: A numerical ID representing a standard target position on the court (e.g., baseline, service line, corner). (See important note below)
Crucial Point: How Elevation and Court Position ID Interact
One of the most important things to understand about the Version 2 JSON format is how the app handles the elevation
value during import, particularly in relation to the courtPositionId
:
Calculated Elevation (Based on Court Position): If the courtPositionId
for a shot is 0
or greater (courtPositionId >= 0
), the Spinfire app assumes you want the ball directed towards a standard court position. During import, it will calculate the required elevation based on the speed
, spin
, and the target courtPositionId
. In this case, the specific elevation
value listed in the JSON for that shot is IGNORED. This is why you might see an elevation value in the JSON (like 200) but the app shows a different calculated value (like 140) after import if courtPositionId
is not -1.
Manual Elevation (Using the JSON Elevation Value): If the courtPositionId
for a shot is -1
, this signals to the app that the elevation for this shot was set manually (not targeting a standard court position). In this situation, the app uses the elevation
value specified in the JSON during import.
What This Means for Importing/Exporting:
- Setting Elevation Manually in the App: When you adjust the elevation for a shot using the Spinfire app’s user interface and are not selecting a specific court position preset, the app is designed to automatically set the
courtPositionId
for that shot to-1
when you export the drill. This ensures your manual elevation setting is preserved in the JSON. - Manually Editing the JSON File: If you are manually editing the Version 2 JSON file in a text editor and you change the
elevation
value for a shot, you must also change the correspondingcourtPositionId
for that shot to-1
if you want your modified elevation value to be respected when you import the file. If you leave thecourtPositionId
as0
or higher, the app will recalculate the elevation based on that court position ID and ignore your change to theelevation
value.
Example of Manual Elevation in JSON (Version 2):
{
"id": 3,
"name": "My Manual Elevation Drill",
"shots": [
{
"interval": 16,
"speed": 7,
"spin": 5,
"elevation": 200, <--- Your desired manual elevation
"horizontal": 0,
"courtPositionId": -1 <--- MUST be -1 for the 200 elevation to be used
}
],
"version": 2,
"sortOrder": 0,
"notes": "This drill uses a specific elevation",
"imagePath": "",
"videoUrl": ""
}
Notice how the courtPositionId
is set to -1
to ensure the elevation
of 200
is used upon import.
Troubleshooting Import Issues:
- Ensure Latest App Version: Make sure both you and the person you are sharing with are using the latest version of the Spinfire app for best compatibility with Version 2 JSON files.
- Check
courtPositionId
: If a manually set elevation value from the JSON isn’t being applied after import, open the JSON file and check thecourtPositionId
for the shot in question. If you want the manual elevation to be used, this value must be-1
. If you edited the file manually, ensure you changed bothelevation
andcourtPositionId
. - Unique Drill Name: When importing, ensure the drill name is unique if you intend to add it as a new drill rather than potentially overwriting an existing one with the same name.
- JSON Syntax: Manually editing JSON can introduce errors. Even a missing comma or misplaced bracket can prevent the file from importing. Use a JSON validator tool if you are unsure.
By understanding the relationship between the elevation
and courtPositionId
fields in the Version 2 JSON format, you can better manage your custom drills and ensure they import with the settings you intend.