gnss-solver

GNSS position solver for Semtech LR1110 / LR1120 trackers

Your tracker heard the satellites; we tell you where it was. LR1110 and LR1120 chips don't compute a position, they send a tiny packet of what they heard. Paste that packet here, or send it to the API, and get the location back with an honest "give or take" in metres.

Position estimates from the GPS and BeiDou measurements in your packet. Accuracy and availability depend on signal quality and satellite geometry. No account needed to try. Free for hobbyists, and a quarter of the price of AWS Device Location when you grow.

1
Your device listens for a few secondsThe LR1110 captures a snapshot of GPS and BeiDou signals. It uses very little power and never needs a full GPS fix.
2
It sends a packet the size of a text messageAbout 50 bytes, over LoRaWAN, Bluetooth or a cable. That packet is what you paste below.
3
We work out where it wasUsing the satellites' published orbits. Most solves are quick; difficult packets can take several seconds. Results include an accuracy estimate and an acceptance decision.

Try it

No packet handy? Load a simulated sample for a public location and press Solve to see what a result looks like.

Payload encoding and framing

For scan groups, send each scan separately. Other modem/TLV wrappers must be removed by your integration.

Approximate location and legacy inputs

Unassisted NAV3 packets (2B) require an approximate latitude and longitude within 50 km. Other supported NAV3 packets carry their own location seed. Time uncertainty and the satellite list below are legacy inputs.

Nothing you paste is stored; packets are solved in memory and dropped.

Show the raw response

What it costs

Free for hobbyists, a quarter of the price of AWS Device Location for everyone else. No licence, no servers to run: send packets, get positions.

Free

$0
Hobbyists, students, small projects
  • Up to 5,000 solves a month
  • Enough for a handful of trackers reporting hourly
  • No card, no account to start
  • Community support by email

Pay as you go

US$0.25 per 1,000 solves
Above the free 5,000 a month
  • Volume rates: $0.25 per 1,000 up to 1M solves a month, $0.20 to 5M, $0.175 above; contact us to arrange paid access
  • GPS and BeiDou position estimates
  • API key, usage reporting, email support

Enterprise

Enquire
Fleets that need commitments
  • Discuss response-time requirements and a named contact
  • Private deployment on request
  • Invoicing, custom limits

Anonymous trial: currently up to 170 requests per UTC day and 6 per minute, shared by clients on the same public IP. Rejected or invalid solve requests also count toward these limits. HTTP 429 means a limit was reached. Ask for a key for an agreed allowance, including the free 5,000/month plan; daily and per-minute limits still apply. Paid access and billing are arranged by email before use, not started automatically by pasting a packet.

Get an API key   or just ask a question

Questions people ask

How accurate is it, really?

Accuracy and availability depend on satellite geometry, signal quality and the measurements in each packet. A result marked accepted has passed the configured checks; it can still be wrong. Use the reported horizontal accuracy as an estimate, not a guaranteed limit, and exclude rejected results from tracking. Rejection explanations distinguish weak geometry, inconsistent measurements and actual nonconvergence.

Do I need an account or a card to try it?

No. Paste a packet or load the sample, or call the API straight away; the anonymous trial is limited by public IP. See the daily and per-minute limits above. Ask for a key to arrange your monthly allowance or usage reporting.

Which chips and packets work?

Semtech LR1110 and LR1120 (for example Seeed's Wio Tracker WM1110, and boards built on the same chip). Supported NAV3 variants include GPS and GPS + BeiDou. Some sparse or unsupported-time packets (including descriptor-zero) are rejected, and BeiDou-primary acceptance is disabled. NAV1 and stationary multi-capture use a separate legacy solver contract. Chip compatibility does not mean every packet can produce an accepted position. If you want help with an unusual packet, contact us before sharing its location data.

What happens to my data?

Packets are solved in memory and dropped. We keep counters (how many solves per day), not payloads or positions. Self-hosted, nothing leaves your servers at all.

How does the price compare to AWS?

Our starting paid rate is US$0.25 per 1,000 solves, compared with AWS Device Location’s published starting rate of US$1.00 per 1,000 locations. See AWS pricing for regional rates and free-tier conditions (starting rate checked 13 September 2026). Accuracy and availability vary by packet; this price comparison is not a claim of equivalent performance on every capture.

Can I run it on my own servers?

The service is hosted; that is what keeps it cheap and current with new firmware. Private deployments are available for enterprise customers who need them; ask us.

Why not just use AWS?

You can; it works. This offers a lower starting price, a free allowance for small projects, and direct email support. Compare both services on your own packets: neither acceptance nor agreement between solvers is a guaranteed error bound. If AWS is already in your stack and the bill doesn't bother you, stay there.

Try it with your own board

Capture raw GNSS packets over USB and send them to this API with our small capture kit. Includes editable firmware source, a Python serial collector and setup instructions.

Wio Tracker 1110 / WM1110

Application UF2 plus source for the nRF52840 + LR1110 board. Requires its compatible existing UF2 bootloader and S140 v6.1.1. Installation replaces the current application.

ESP32 + LR1110

Source template with configurable pins, antenna control and clock settings. Check your module wiring before building. No universal ESP32 binary is included.

Download capture kit v0.1.3 ZIP · 92 KiB · source + WM1110 UF2 (bundled almanac)

Evaluation build: both targets compile; the WM1110 application completed two local assisted scans and recovered from a deliberately stale almanac on a spare board, with a matching CRC and another complete assisted scan. This validates packet collection, not position accuracy. ESP32 remains a source template. USB/serial only — no Bluetooth or Cat Tracker app connection. The kit collects packets; positioning runs through the hosted API. It contains no API key or server solver source.

Unzip, read the README for your board, then collect a few stationary open-sky scans. Logs stay on your computer unless you explicitly enable API submission. Normal API limits apply. Review location-sensitive logs before sharing them privately for feedback.

Verify the download

SHA-256:

2dbaa921c24c9d5f362c0ea77bbc093535d4bb42600122aa9be0a12558e43dcb

The archive also includes a file manifest, build information and dependency licences.

For developers

The same solver behind this page, as a plain HTTP API. Send the packet, get JSON back.

Solve one packet
curl -X POST https://gnss-solver.com/v1/solve/lr11xx -H "content-type: application/json" -d '{
  "format": "nav3",
  "payload": "<0x040D result hex, destination byte optional>",
  "gps_week": 2435
}'

Replace 2435 with the full GPS week of your capture; it is an example, not a permanent setting. If you have a key, add -H "x-api-key: YOUR_API_KEY". Omit that header for the anonymous trial. Keep keys on your backend, not in publicly served code.

Response: { position: {lat, lon, alt}, horizontal_accuracy_m, satellites_used, accepted, confidence, quality: { residual_rms_m, geometry }, solve_ms }. Use only accepted: true results. Rejections include reason codes. horizontal_accuracy_m is an estimate, not a guaranteed error limit; measurement_epoch_gpst identifies the solver’s estimated observation epoch, which may differ from upload time.

Check the HTTP status as well as accepted. An HTTP 200 rejection is a positioning decision; retrying the same packet with the same orbit data does not improve it. For HTTP 429, respect Retry-After if present; otherwise back off for a per-minute limit or wait until the next UTC day for a daily limit. For temporary service errors or timeouts, retry with increasing delays and a small retry limit.

Example response shapes (illustrative, fields omitted):

{ "accepted": true, "position": { "lat": 49.30171, "lon": -123.14166, "alt": 30 }, "horizontal_accuracy_m": 20 }
{ "accepted": false, "position": null, "reasons": ["invalid-nav3-structure"] }
Control the accuracy you accept

Optional fields on the solve request let you choose how strict the acceptance is, from a tight pin to a rough area:

curl -X POST https://gnss-solver.com/v1/solve/lr11xx -H "content-type: application/json" -d '{
  "payload": "<hex>", "gps_week": 2435,
  "mode": "precision",            // only accept fixes ≤ 40 m (or "balanced" = ≤ 90 m)
  "max_accuracy_m": 50            // OR your own ceiling: reject anything worse than 50 m
}'
  • "mode": "precision" — accept only fixes with an estimated accuracy ≤ 40 m, else reject.
  • "mode": "balanced" — the same at ≤ 90 m.
  • "max_accuracy_m": N — your own ceiling; if mode is also set, the tighter ceiling applies. Rejects any fix whose horizontal_accuracy_m is worse than that ceiling.
  • Omit both — accept whatever the strict solver already trusts (no accuracy cap).

Low-power / best-effort mode. For sparse-sky single scans that the strict solver rejects, opt in to a weaker fix that is reported honestly and sanity-checked against your last known position:

curl -X POST https://gnss-solver.com/v1/solve/lr11xx -H "content-type: application/json" -d '{
  "payload": "<hex>", "gps_week": 2435,
  "best_effort": true,
  "anchor": { "lat": 48.6, "lon": -123.5 },   // last known position (optional but recommended)
  "anchor_max_km": 5                           // reject fixes this far from the anchor (default 5)
}'
  • Accepts lower-redundancy fixes the strict solver would refuse; the response is tagged "mode": "best_effort" with a low confidence.
  • Best-effort reports at least 75 m of uncertainty. That final reported value must pass your accuracy ceiling; mode: "precision" (40 m) therefore rejects best-effort fixes.
  • horizontal_accuracy_m is floored so it never claims false precision — treat it as a rough area, not a pin.
  • The anchor gate drops implausibly-far solutions (a common failure of weak fixes); a rejected one returns code: "anchor-distance-exceeded".
  • The default strict behaviour is unchanged unless you set best_effort. Leave it off for anything safety- or billing-sensitive.
Solve several packets from a stationary device (multi-capture)
curl -X POST https://gnss-solver.com/v1/solve/lr11xx/multi -H "content-type: application/json" -d '{
  "captures": [
    { "payload": "<scan 1 hex>", "capture_time_gpst": 1472142795, "detected_sats": [ ... ] },
    { "payload": "<scan 2 hex>", "capture_time_gpst": 1472142817, "detected_sats": [ ... ] },
    { "payload": "<scan 3 hex>", "capture_time_gpst": 1472142839, "detected_sats": [ ... ] }
  ],
  "assist_position": { "lat": 49.28, "lon": -123.12 }
}'

2–6 captures within an hour, solved together with one shared position; a bad scan is dropped automatically. Same response shape plus frames: { given, solved, used, dropped }. Counts as one solve.

Daily almanac image for the chip
curl https://gnss-solver.com/v1/almanac/full

A fresh full-almanac image built from public data every day, in the shape the old LoRa Cloud endpoint returned, so existing firmware keeps working.

Supply the full GPS week for a NAV3 scan; legacy clients may supply GPS seconds as week context. The default NAV3 solver uses packet measurements. Unassisted 2B packets also require assist_position with lat/lon within 50 km; other supported variants use their embedded seed. Only timing variants validated by this solver are eligible for acceptance. BeiDou-primary acceptance remains disabled. NAV1 and stationary multi-capture use the legacy input contract.

Talk to a person

Building a tracker, running a fleet, or just curious whether your packets will solve? Write to [email protected]. We reply within one business day, and we like odd packets.

Trial terms and privacy

Developers may explicitly opt in to private rejected-payload diagnostics with allow_debug_payload_retention: true; when enabled by the operator, up to the first 32 payload bytes may be retained for at most 30 days. This demo does not opt in.

Privacy. By default, packets and positions you submit are solved in memory and discarded; the optional rejected-payload diagnostics described above are the exception. We do not retain solved positions through this option. We keep aggregate counters (solves per day) and a short-lived, hashed client identifier for rate limiting. The page uses privacy-friendly, cookieless, self-hosted analytics (Umami) that records only aggregate page visits, with no cookies, no personal data and no cross-site tracking; it loads no advertising or tracking scripts, and fonts are served from this site. Map tiles are fetched from OpenStreetMap when a result is shown, which reveals only the map area to them. Emails you send us are kept to answer them.

Trial terms. The hosted endpoint is a free trial for evaluation: fair-use daily limits, no uptime commitment, results provided as-is without warranty. Don't rely on it for safety-critical use. Paid access requires an agreed plan; the anonymous trial does not automatically create a paid account. There is no licence to buy.