Documentation

Partner API reference

Hosted access to the Strelok ballistics engine over HTTPS. Send JSON, get a full trajectory, a trued velocity, or hit probability by range.

Overview

The Partner API exposes the hosted pro solver behind the Strelok desktop apps. All endpoints accept a JSON body via HTTPS POST and return JSON. The base URL is https://api.strelokpro.com.

Access is by request. There is no self-serve signup; see Getting a key or request access.

EndpointWhat it does
POST /api/partner/v1/solveFull trajectory solution with stability and transonic annotations.
POST /api/partner/v1/trueTrajectory truing: fit muzzle velocity (and optionally BC) to observed drops.
POST /api/partner/v1/montecarloMonte Carlo hit probability by range for a rectangular target.

Requests must be sent with Content-Type: application/json. All three endpoints share one set of base solve fields, listed under Common request fields below; each endpoint adds a few fields of its own.

Authentication

Every request is authenticated with your partner API key, a secret that starts with sk_strelok_. Pass it in the Authorization header:

Authentication
Authorization: Bearer sk_strelok_YOUR_KEY

The X-Api-Key header is also accepted with the same key as its value, for clients that cannot set an Authorization header.

Keep your key server-side
Treat the key like a password. Call the API from your backend only; never embed the key in a mobile app, web page or public repository. If a key is exposed, contact us and we will rotate it.

Rate limits

Default limits are 60 requests per minute and 5,000 requests per day, per key. Higher limits are available; contact us if your integration needs them.

When a limit is exceeded the API returns HTTP 429 with a retryAfter value in the response body, in seconds, and the same value in a standard Retry-After response header. Wait at least that long before retrying, and prefer exponential backoff on repeated 429s. The daily count resets at midnight UTC.

Common request fields

These fields describe the rifle, load, atmosphere and wind. They are shared by all three endpoints. Values outside the listed range are rejected with HTTP 400.

Required

FieldRequiredUnits / rangeDescription
muzzleVelocityYesfps, 100 to 5000Muzzle velocity.
ballisticCoefficientYes0.01 to 2.0Ballistic coefficient in the model set by dragModel.
bulletWeightYesgrains, 1 to 1000Bullet weight.
sightHeightYesinches, 0 to 10Sight height above the bore axis.
zeroRangeYesyards, 10 to 3000Range at which the rifle is zeroed.
maxRangeYesyards, 10 to 5000Furthest range to solve to.
rangeStepYesyards, 1 to 500Output interval between trajectory rows.

Optional

FieldRequiredUnits / rangeDescription
dragModelNo"G1" or "G7"Drag model for the BC. Default "G1".
temperatureNodeg F, -60 to 140Air temperature. Default 59.
pressureNoinHg, 15 to 35Station pressure. Default 29.92.
altitudeNofeet, -1000 to 30000Altitude above sea level. Default 0.
humidityNopercent, 0 to 100Relative humidity. Default 50.
windSpeedNomph, 0 to 200Wind speed. Default 0.
windDirectionNodegrees, 0 to 360Direction the wind comes from, clock style: 90 is a full-value wind from 3 o'clock. Default 90.
shootingAngleNodegrees, -90 to 90Incline or decline angle of the shot. Default 0.
includeSpinDriftNobooleanInclude spin drift in windage output. Default false.
includeCoriolisNobooleanInclude Coriolis effect. Default false.
twistRateNoinches/turn, -30 to 30, not 0Barrel twist rate; negative for left-hand twist. Default 10.
bulletDiameterNoinches, 0.1 to 1.0Bullet diameter. Default 0.308.
bulletLengthNoinches, 0.1 to 5.0Bullet length, used for stability and spin drift. Default 1.24.
latitudeNodegrees, -90 to 90Shooter latitude, used for Coriolis. Default 45.
targetAzimuthNodegrees, 0 to 360Bearing to the target, used for Coriolis. Default 0.
Sign convention
In responses, dropInches, dropMOA and dropMil are positive below the line of sight past the zero. The path field is the bullet path relative to the sight line, so it is negative where the bullet is below it.

POST /api/partner/v1/solve

Returns the full trajectory at each rangeStep, annotated with Mach number, supersonic, transonic or subsonic zone, gyroscopic stability (Miller Sg) and the first transonic and subsonic ranges.

Additional request fields

FieldRequiredUnits / rangeDescription
bcBandsNoarrayVelocity-banded multi-BC: [{ "minVelocity": fps, "bc": value }, ...] sorted from highest minVelocity down. The first band at or below the muzzle velocity sets one BC for the whole trajectory; if the muzzle velocity is below every band, the last band is used. Each row's bcUsed is the band for that row's velocity, for reference only: it is not the BC the row was computed with. Without bcBands, ballisticCoefficient is used.

Example request

6.5 Creedmoor, 140 gr, G7 0.315, 100 yard zero, 10 mph full-value wind:

POST /api/partner/v1/solve
curl https://api.strelokpro.com/api/partner/v1/solve \
  -H "Authorization: Bearer sk_strelok_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "muzzleVelocity": 2710,
    "ballisticCoefficient": 0.315,
    "dragModel": "G7",
    "bulletWeight": 140,
    "sightHeight": 1.8,
    "zeroRange": 100,
    "maxRange": 1200,
    "rangeStep": 100,
    "temperature": 59,
    "pressure": 29.92,
    "windSpeed": 10,
    "windDirection": 90,
    "includeSpinDrift": true,
    "twistRate": 8,
    "bulletDiameter": 0.264,
    "bulletLength": 1.427
  }'

Example response (abridged)

200 OK
{
  "trajectory": [
    { "range": 100.2, "velocity": 2565.2, "time": 0.114, "energy": 2045.2,
      "dropInches": 0.0, "dropMOA": 0.0, "dropMil": 0.0,
      "windDriftInches": 0.61, "windDriftMOA": 0.58, "windDriftMil": 0.17,
      "path": -0.0, "mach": 2.298, "bcUsed": 0.315, "zone": "supersonic" },
    { "range": 200.3, "velocity": 2424.1, "time": 0.2345, "energy": 1826.4,
      "dropInches": 3.51, "dropMOA": 1.67, "dropMil": 0.49,
      "windDriftInches": 2.49, "windDriftMOA": 1.19, "windDriftMil": 0.34,
      "path": -3.51, "mach": 2.171, "bcUsed": 0.315, "zone": "supersonic" },
    { "range": 1200.1, "velocity": 1242.6, "time": 1.9625, "energy": 479.9,
      "dropInches": 534.37, "dropMOA": 42.53, "dropMil": 12.37,
      "windDriftInches": 123.19, "windDriftMOA": 9.8, "windDriftMil": 2.85,
      "path": -534.37, "mach": 1.113, "bcUsed": 0.315, "zone": "transonic" }
  ],
  "stability": { "sg": 1.51, "rating": "stable" },
  "transonicRangeYards": 1200.1,
  "subsonicRangeYards": null
}

Trajectory row fields: range (yards), velocity (fps), time (seconds), energy (ft-lb), dropInches, dropMOA, dropMil, windDriftInches, windDriftMOA, windDriftMil, path (inches relative to the sight line), mach, bcUsed, and zone (supersonic, transonic or subsonic). The stability rating is stable at Sg 1.5 or above, marginal from 1.0 to 1.5, and unstable below 1.0. transonicRangeYards and subsonicRangeYards are the first ranges where the bullet enters each zone, or null if it never does within maxRange.

POST /api/partner/v1/true

Trajectory truing. Given the base solve fields plus drops you actually observed on target, the solver searches muzzle velocity (within plus or minus 200 fps) and optionally a BC scale factor (within plus or minus 15 percent) for the combination that best matches your observations, minimizing RMS error in MOA.

Additional request fields

FieldRequiredUnits / rangeDescription
observationsYesarrayObserved drops: [{ "rangeYards": n, "dropMOA": n }, ...]. Use the same sign convention as the trajectory output: positive dropMOA below the line of sight. At least one observation is required (at most 100), each must be an object with numeric rangeYards and dropMOA, and three or more at spread ranges give a much better fit.
trueBCNobooleanAlso search a BC scale factor in addition to muzzle velocity. Default false. When true, maxRange and all observations must be within 2000 yards (the wider search is more expensive); the muzzle-velocity-only default has no such limit.

Example request

POST /api/partner/v1/true
curl https://api.strelokpro.com/api/partner/v1/true \
  -H "Authorization: Bearer sk_strelok_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "muzzleVelocity": 2710,
    "ballisticCoefficient": 0.315,
    "dragModel": "G7",
    "bulletWeight": 140,
    "sightHeight": 1.8,
    "zeroRange": 100,
    "maxRange": 1000,
    "rangeStep": 100,
    "twistRate": 8,
    "bulletDiameter": 0.264,
    "bulletLength": 1.427,
    "observations": [
      { "rangeYards": 300, "dropMOA": 4.5 },
      { "rangeYards": 600, "dropMOA": 14.3 },
      { "rangeYards": 900, "dropMOA": 27.6 }
    ]
  }'

Example response

200 OK
{
  "muzzleVelocity": 2636.4,
  "bcScale": 1.0,
  "rmsErrorMOA": 0.059,
  "before": { "rmsErrorMOA": 1.132 }
}

muzzleVelocity is the trued velocity in fps, bcScale is the multiplier to apply to your BC (1.0 when trueBC is false), rmsErrorMOA is the residual error of the trued solution against your observations, and before.rmsErrorMOA is the error the untrued inputs produced. A request with an empty or missing observations array returns HTTP 400.

POST /api/partner/v1/montecarlo

Hit probability by range for a rectangular target, given velocity, wind and aiming dispersion. Each run perturbs muzzle velocity, wind and optionally BC, resolves the trajectory, adds aiming error, and scores a hit if the impact falls inside the target box centered on the nominal aim point.

Additional request fields

FieldRequiredUnits / rangeDescription
runsNo1 to 5000Number of simulated shots. Default 500.
targetWidthInchesNoinches, 0.1 to 1000Target width. Default 18.
targetHeightInchesNoinches, 0.1 to 1000Target height. Default 24.
mvSDNofps, 0 to 500Muzzle velocity standard deviation. Default 15.
windSDNomph, 0 to 100Wind speed standard deviation. Default 3.
bcCVNoratio, 0 to 1BC coefficient of variation, e.g. 0.01 for 1 percent. Default 0.
aimErrorMOANoMOA, 0 to 50One-sigma aiming error. Default 0.5.
seedNointegerRandom seed. The simulator is deterministic: the same request with the same seed returns the same result. Default 12345.
Compute budget
A single request is bounded by runs multiplied by maxRange, which must be at most 500,000. Requests over the budget return HTTP 400; reduce runs or maxRange. For example 300 runs to 1500 yards is 450,000, well within budget. At the default of 500 runs, maxRange can be at most 1000 yards. For larger studies, split the work across requests with a different seed on each and combine the results; identical requests return identical results and add no samples.

Example request

POST /api/partner/v1/montecarlo
curl https://api.strelokpro.com/api/partner/v1/montecarlo \
  -H "Authorization: Bearer sk_strelok_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "muzzleVelocity": 2710,
    "ballisticCoefficient": 0.315,
    "dragModel": "G7",
    "bulletWeight": 140,
    "sightHeight": 1.8,
    "zeroRange": 100,
    "maxRange": 1200,
    "rangeStep": 100,
    "windSpeed": 10,
    "windDirection": 90,
    "twistRate": 8,
    "bulletDiameter": 0.264,
    "bulletLength": 1.427,
    "runs": 400,
    "targetWidthInches": 18,
    "targetHeightInches": 24,
    "mvSD": 12,
    "windSD": 3,
    "aimErrorMOA": 0.5
  }'

Example response (abridged)

200 OK
{
  "runs": 400,
  "byRange": [
    { "range": 100.2, "hitPct": 100.0, "meanDropInches": 0.0, "meanWindInches": 0.53 },
    { "range": 200.3, "hitPct": 100.0, "meanDropInches": 3.5, "meanWindInches": 2.17 },
    { "range": 1100.0, "hitPct": 22.5, "meanDropInches": 418.99, "meanWindInches": 87.14 },
    { "range": 1200.1, "hitPct": 20.2, "meanDropInches": 534.26, "meanWindInches": 107.84 }
  ],
  "maxEffectiveRange": 500.2
}

byRange has one entry per rangeStep with the hit percentage and the mean drop and wind drift in inches across all runs. maxEffectiveRange is the furthest range where the hit probability is at least 90 percent, or null if no range qualifies.

Error reference

Errors are returned as JSON with an error message and a conventional HTTP status code.

StatusMeaning
400 Bad RequestValidation failed. The error message names the offending field, e.g. a missing required field or a value outside its allowed range.
401 UnauthorizedThe API key is missing, malformed or unknown.
403 ForbiddenThe API key is valid but has been revoked. Contact us to have it reinstated or replaced.
429 Too Many RequestsRate limit exceeded. The body includes retryAfter, the number of seconds to wait before retrying; the same value is sent in the Retry-After header.
500 Internal Server ErrorUnexpected solver failure. Safe to retry; if it persists, contact us with the request body.
503 Service UnavailableThe key could not be checked right now. Nothing was solved; retry after a short wait.

Example error bodies

Errors
HTTP 400
{ "error": "muzzleVelocity is required" }

HTTP 401
{ "error": "Invalid API key." }

HTTP 403
{ "error": "API key revoked." }

HTTP 429
Retry-After: 60
{
  "error": "Rate limit exceeded",
  "message": "Rate limit exceeded (60 requests/minute).",
  "retryAfter": 60
}

Getting a key

Partner API keys are issued by contacting [email protected]. Include a short description of your integration and the request volume you expect. You can also reach us through the contact page.