SpotterCam Target Shooting System

Support

Something not working, or not working the way you expected? Send it over and include what the app can tell us.

Contact

support@spottercam.com

Tell us what you were doing, what you expected, and what happened instead. If the app produced a support bundle (below), attach it — it usually turns a week of back-and-forth into one reply.

What a support ticket from the app contains

SpotterCam's Support section builds a small bundle and asks you before it sends anything. It is a zip plus a short description, and you can open the zip and look at it first.

What never leaves your box automatically. Colour stills, session recordings, the live stream, your target photos and your round history stay on your machine. Nothing is sent home in the background — a ticket goes only when you tap send, and a recording goes only if we ask for it and you choose to upload it.

For whoever builds the receiver Not live yet

This section documents the contract so the hosting side and the app side can be built independently. The endpoint below is not yet running; tickets go by email today.

Request

POST https://spottercam.com/support/ticket.php, as multipart/form-data:

PartTypeWhat
metaJSON text Ticket metadata (below). Required.
bundlefile, application/zip The logs/settings zip. Optional but normal. Cap 25 MB.

The meta JSON:

{
  "v": 1,
  "kind": "bug" | "question" | "feedback",
  "subject": "Ghost confirms on a windy target",
  "body": "free text the operator typed",
  "contact": "rob@example.com",
  "app": { "version": "1.4.2", "build": "2026-09-21T10:04:00Z", "sha": "0a52b5e" },
  "machine": { "os": "Windows 10 19045", "role": "field", "id": "<stable random per install>" },
  "session": { "recording": "session_rec_20260921_100400", "round": 3 },
  "bundle": { "name": "support_20260921_100400.zip", "sha256": "…", "bytes": 1841203 }
}

Response

200 { "ok": true,  "ticket": "SC-20260921-0007" }
413 { "ok": false, "error": "bundle too large" }
400 { "ok": false, "error": "bad meta" }
429 { "ok": false, "error": "rate limited" }

The app shows the ticket id to the operator and writes it to the log, so a later email can reference it.

What the receiver has to do

  1. Validate meta as JSON and reject anything over a few KB.
  2. Reject a bundle that is not a zip or is over the size cap, before reading it.
  3. Store the pair under a generated ticket id, outside the web root.
  4. Email Rob a notification with the subject, body and the stored path — not the zip itself.
  5. Rate-limit per install id and per IP.
  6. Never echo any submitted field back into an HTML page.

A worked PHP sketch of exactly that is in support/ticket.php.example in the site source. It is an example, not a deployment: read it, then decide what you actually want running.