System designHow-to

HTTP snapshot URL polling: IP camera still image on a timer

Find the camera's HTTP snapshot URL, poll it on a timer, publish the latest image, handle HTTPS certificates and pick the right IP camera for the job.

LumaSpec Vision10 min read Share on LinkedIn

On this page 9 sections
  1. 01Poll a URL, not a stream
  2. 02Find the camera's snapshot URL
  3. 03Set up the timed poll
  4. 04Publish the latest image to the central server
  5. 05Worked example: one camera, a 10-minute timer, a month of transfer
  6. 06HTTPS, self-signed certificates and credentials
  7. 07When a snapshot camera is the wrong choice
  8. 08Checks before you commit
  9. 09Questions

You want the newest picture from a network camera on a central server, refreshed every 10 minutes or so, and you do not need the video in between. That is a solved problem: most IP cameras hand a JPEG to any HTTP client that asks at the right URL, so a timer, one GET request and an atomic file write are all the infrastructure you need. The steps below show how to find that URL, poll it on a schedule, publish the result, survive certificate and network failures, and recognize the jobs where a surveillance-style camera is the wrong tool.

Poll a URL, not a stream

One image every 10 minutes is 144 requests a day. Holding a video session open for that duty cycle means a decoder, keepalive handling and reconnect logic running so you can discard almost everything the camera sends — at a typical 25 fps that is 90,000 frames an hour, of which you keep 6. A plain HTTP GET of the camera's still-image URL is stateless: it cannot leave a stalled session behind, it restarts cleanly after a power cut, and anything that can fetch a web page can run it.

Commit to this rule: below one frame per second of needed freshness, poll; for continuous video, open a stream. The polling side is what follows here. For the fetch mechanics in code, read grabbing images from an IP camera over an HTTP snapshot URL, and when someone also wants live video, a one-button live view from a remote camera is the lighter route.

Find the camera's snapshot URL

The camera's own web server publishes the still image, and there are three ways to the exact path:

  1. Open the camera's web interface in a browser. Many pages embed the still image; use the browser's developer tools to copy that image's address.
  2. Ask the ONVIF media service. A camera that conforms to ONVIF answers the GetSnapshotUri operation with its still-image URI.
  3. Read the maker's interface documentation. Common patterns are a path such as /onvif-http/snapshot under the camera's own address, or an endpoint ending in .jpg.

Test the result from the poller's network: paste the URL into a browser and reload twice. A working snapshot URL returns a JPEG that changes between reloads, with Content-Type image/jpeg — not a login page, not a redirect.

Watch the query string. If the URL only works while it carries a long token, that token is session authentication and it will expire under you. Choose a camera that accepts HTTP Basic or Digest credentials, so the path stays fixed and the poller supplies the credentials itself. Prefer a camera with a local web interface and wired Ethernet over a cloud-tied model that serves images only through the maker's cloud, and power it over PoE so one drop carries power and data.

Set up the timed poll

You need the snapshot URL, a host with an HTTP client and a scheduler, and write access to the folder the central side reads.

  1. Fetch once by hand and record the status code, the Content-Type and the image size in kB. That measured size is the S in the transfer arithmetic below.
  2. Set a 10-second timeout and two attempts per cycle. A camera that has not answered in 10 seconds is down for this cycle; move on.
  3. Validate before publishing: status 200, Content-Type image/jpeg, and a body that starts with the JPEG marker bytes FF D8. This is what stops an HTML error page from overwriting a good image.
  4. Write the body to a temporary file on the same filesystem as the published path, then rename it onto the published path. The rename is atomic, so a reader never catches a half-written file.
  5. Write the capture time to a small timestamp file beside the image.
  6. Schedule the cycle every 10 minutes from your platform's scheduler, and log each outcome — success, timeout, rejection — with a reason.

In pseudo-code, with helper names of our own — substitute your platform's HTTP client:

snapshot_url: str = 'http://192.168.1.50/onvif-http/snapshot'
interval_min: int = 10
timeout_s:    int = 10
attempts:     int = 2
staging:      str = '/srv/cam/latest.jpg.tmp'
published:    str = '/srv/cam/latest.jpg'

for attempt in range(attempts):
    r = http_get(snapshot_url, timeout_s)
    if r.status == 200 and r.content_type == 'image/jpeg' and r.body[0:2] == b'\xff\xd8':
        write_file(staging, r.body)
        atomic_rename(staging, published)
        write_file(published + '.ts', timestamp_now())
        break

The test that proves it: run the cycle twice, one interval apart, and fetch the published path from a second host. Pass is Content-Type image/jpeg and a modification time newer than the first run. A cycle that hangs instead of failing cleanly is a client-side wait problem, and troubleshooting image grab wait timeouts walks that diagnosis.

Publish the latest image to the central server

Two topologies cover every case. When the central server can reach the camera — same network, routed subnet or VPN — run the poller on the central server itself: one moving part, nothing to maintain at the camera end. When the camera sits at a remote site behind address translation, run the poller on a small host beside the camera and push the finished file to the central server over HTTP or SCP. Both end the same way: one latest.jpg plus one timestamp, overwritten in place, nothing archived unless you choose to keep history later.

If the central side is a SCADA or middleware platform, check for a built-in HTTP image data source before writing a poller. Many platforms take a snapshot URL as a point and poll it on a schedule for you; downloading an IP camera snapshot through a SCADA HTTP client is that pattern worked end to end.

Worked example: one camera, a 10-minute timer, a month of transfer

Inputs, each with its source:

  • Interval T = 10 min — the publishing requirement.
  • Snapshot size S = 400 kB — read off one real fetch from your camera; full-HD JPEGs normally land between 100 kB and 500 kB, and every number below scales linearly with S.
  • Timeout 10 s and two attempts per cycle — the poller settings above.
images per day = 1440 / T transfer per month = S × (1440 / T) × 30 worst-case age at the server = T + timeout × attempts

Arithmetic: 1,440 min per day ÷ 10 min = 144 images a day. 144 × 30 = 4,320 images a month. 4,320 × 400 kB = 1,728,000 kB, about 1.7 GB per camera per month, with request and header overhead under 1% of that. Worst-case age after a good cycle is 10 min + 2 × 10 s = 10 min 20 s, and each missed cycle adds one interval, so the picture a viewer sees can be 30 min old by the third attempt — set the failure alert at three consecutive misses.

The decisions this buys: one camera at this size fits any ordinary site link. Ten cameras total about 17 GB a month, still modest, but on a cellular uplink poll on the plant side and publish one resized copy instead of ten originals. Keeping history costs the same 1.7 GB per camera-month of disk, so a year of one camera is roughly 20 GB.

HTTPS, self-signed certificates and credentials

Run the poll over HTTPS where the camera supports it. On plain HTTP the picture and the credentials cross the segment in the clear, readable by anything that can sniff that VLAN. The catch is the certificate: a camera's factory self-signed certificate is refused by a default HTTP client, and that refusal is the client doing its job.

Two clean fixes, best first:

  1. Issue the camera a certificate from your own certificate authority — generate the request on the camera, sign it, install it — and trust that authority in the poller.
  2. Export the camera's self-signed certificate and add that single certificate, for that single host, to the poller's trust store.

Keep credentials in the poller's configuration, out of the URL and out of the log lines; a URL with an embedded password has a way of ending up in screenshots and tickets.

When a snapshot camera is the wrong choice

Polling answers one question: what does it look like right now? Three jobs need more. Freshness under about 10 seconds is a stream job — displaying an RTSP stream in an HMI covers the live path, and budget for hidden frame buffering in an encoded pipeline when you measure its latency. Any measurement — width, presence, a defect call — needs repeatable pixels, and repeatable pixels need manual exposure, a shutter that does not bend moving edges and controlled light; that is the territory where industrial camera interfaces still win. And once several cameras share one switch, plan the ports first, as in GigE network planning for switch ports and bandwidth.

Snapshot IP camera Machine-vision camera
Best at Observing, archiving, awareness Measuring, inspecting, triggering
Freshness One frame per poll Full frame rate, deterministic trigger
Exposure Scene auto modes, frame-to-frame changes Manual, fixed values
Shutter Rolling on consumer sensors Global on most industrial sensors
Light Whatever the scene provides Controlled strobe and constant lighting
Access HTTP GET of a still URL GenICam-controlled stream

When the job crosses that line, change the shopping list. Our range is the machine-vision side; if you need more detail than a snapshot sensor resolves, start from the MV-CS200-10GC, a 20 MP GigE area scan camera:

Area scan camerasHikrobot MV-CS200-10GC 20 MP Area Scan Camera, GigE, IMX183, Color, BasicMV-CS200-10GC
Sensor format
1"
Lens mount
C-mount
Interface
GigE
Resolution
16-25 MP
$739.00View partBuild a system with it

Give it a data cable that covers the drop — the LS-CBL-0117 is a 15 m RJ45 camera data cable:

CablesCamera Data Cable, RJ45 (with locking stud), Bend (up) to RJ45, 15 m (LS-CBL-0117)LS-CBL-0117
Type
Camera data cables
Length
15 m
$89.00View partBuild a system with it

A twisted-pair segment reaches 100 m per the Ethernet standard before it needs a switch in between, which covers most camera-to-switch runs; the cables range adds high-flex and screw-lock variants for moving or electrically noisy installs. And because a measurement image is only as repeatable as its light, drive the illumination from one of the light controllers — the LS-CTL-0322 is a 4-channel digital LED light controller:

Light controllers4-Channel Digital LED light controller, 16-24V, AC100-240V 50/60 Hz, 8 A total output (LS-CTL-0322)LS-CTL-0322
Output
Constant voltage 24 V
Channels
4 channels
Control
Digital
$539.00View partBuild a system with it

Filter area scan cameras by mount, shutter and interface in the camera finder, and the rest of the chain — lens, light, controller — follows from the sensor you land on.

Checks before you commit

  • A manual fetch from the poller's network returns status 200, Content-Type image/jpeg, and a JPEG that changes on reload.
  • The snapshot size is measured and the monthly transfer computed with the formula above.
  • The certificate route is chosen — your own authority, or one trusted host certificate — and the checks stay on.
  • Credentials sit in the poller config, out of the URL and out of the logs.
  • The scheduler runs the cycle every 10 minutes as a service, with per-cycle logging.
  • A failed cycle keeps the last good image and its timestamp; an alert fires after three consecutive misses.
  • The job is observation. The day pixels become measurements, the list changes to a machine-vision camera, manual exposure and controlled light.

To lay out the full chain in one pass, start with the configurator at the camera step; for questions about the publishing architecture, the contact page reaches us.

Questions

How do I find the snapshot URL of my IP camera?

Open the camera's web interface and copy the address of the still image embedded in its pages. An ONVIF-conformant camera also returns the URI through its media service's GetSnapshotUri operation, and common path patterns look like /onvif-http/snapshot under the camera's own address. The test is a browser reload: the URL must return a fresh JPEG with Content-Type image/jpeg, not a login page or a redirect.

How much data does polling an image every 10 minutes use?

144 images a day and 4,320 a month. At a measured 400 kB per snapshot that is about 1.7 GB per camera per month, and the result scales linearly: halve the interval and the transfer doubles, and a 200 kB snapshot halves it. Request and header overhead stays under 1%, so image size and interval are the only two numbers that matter.

Why does my poller refuse the camera's HTTPS certificate?

Because the certificate is self-signed, and a default HTTP client only trusts certificates that chain to an authority it knows. Fix it at the source: issue the camera a certificate from your own authority, or export the camera's certificate and trust that single certificate for that single host. Do not switch the checks off to make the call pass, because that weakens every other HTTPS connection the host makes.

What should happen when the camera is unreachable at poll time?

Time out after 10 seconds, retry once, then keep the last good image on the server with its timestamp and log the miss. The picture a consumer sees grows one interval older per missed poll — 30 minutes by the third attempt at a 10-minute interval — so raise the alert at three consecutive misses. Never delete the last good file on failure; a missing image is worse than an old one.

When is a snapshot poll the wrong tool?

When you are observing, polling is right. Switch to a stream when someone must see changes within seconds. Switch to a machine-vision camera with manual exposure, global shutter and controlled lighting the moment pixels become measurements — widths, defects, presence checks. A surveillance sensor adjusts its own exposure frame to frame, so the same part can look different between two polls hours apart.