webcam.io API Reference: Automate Your Webcams
The webcam.io API allows you to programmatically control your webcams — update text overlays with live data, enable/disable cameras on schedule, and manage live stream settings.
Overview
What You Can Do
| Feature | Use Case |
|---|---|
| Dynamic text overlays | Display live weather, temperature, sensor data on images |
| Enable/disable webcam | Schedule capture times, maintenance windows |
| Control live streaming | Start/stop streams, change source/destination URLs |
| Automate workflows | Integrate with IoT sensors, home automation, cron jobs |
API Basics
| Property | Value |
|---|---|
| Base URL | https://webcam.io/api/webcams/ |
| Protocol | HTTPS (required) |
| Method | PUT for updates |
| Format | JSON |
| Authentication | Email + API Key (headers) |
Authentication
All API requests require two authentication headers:
| Header | Description | Example |
|---|---|---|
X-Auth-Email |
Your webcam.io account email | user@example.com |
X-Auth-Key |
Your secret API key | 22l7kIX0AwdMcdpo7v |
Get Your API Key
- Log in to webcam.io Dashboard
- Go to Profile (click your email in top right)
- Find API Key section
- Copy your
SECRET-API-KEY
Your API key provides full access to your webcams. Never share it publicly or commit it to version control. Treat it like a password.
Get Your Webcam ID
- Go to Dashboard → Webcams
- The Webcam ID is shown in the list (e.g.,
m7g61z) - Or find it in the URL when viewing a webcam:
webcam.io/webcams/m7g61z
Making API Requests
Request Format
PUT https://webcam.io/api/webcams/{WEBCAM-ID}
Content-Type: application/json
X-Auth-Email: your@email.com
X-Auth-Key: your-api-key
{
"parameter": "value"
}
Basic curl Example
curl -X PUT "https://webcam.io/api/webcams/WEBCAM-ID" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: YOUR@EMAIL" \
-H "X-Auth-Key: SECRET-API-KEY" \
-d '{"dynamic_text1": "Hello World"}'Response
Success (200 OK):
{
"status": "ok",
"webcam_id": "m7g61z"
}Error (4xx/5xx):
{
"error": "Invalid API key"
}API Endpoints
Update Webcam Settings
PUT https://webcam.io/api/webcams/{WEBCAM-ID}
Available Parameters:
| Parameter | Type | Description |
|---|---|---|
dynamic_text1 |
string | Dynamic text overlay var 1 |
dynamic_text2 |
string | Dynamic text overlay var 2 |
dynamic_text3 |
string | Dynamic text overlay var 3 |
interval |
integer | Capture interval in seconds (0 = disabled) |
stream_enabled |
boolean | Enable/disable live streaming |
backup_stream_enabled |
boolean | Enable/disable backup stream |
stream_src_url |
string | Source RTSP URL |
stream_dest_url |
string | Destination RTMP URL |
All parameters are optional — include only the ones you want to change.
Dynamic Text Overlays
Update text displayed on your webcam images in real-time. Perfect for showing live weather data, sensor readings, or custom information.
Update Text Overlay
curl -X PUT "https://webcam.io/api/webcams/m7g61z" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: 22l7kIX0AwdMcdpo7v" \
-d '{"dynamic_text1": "Temperature: 23°C"}'Multiple Text Lines
Update multiple overlay lines in one request:
curl -X PUT "https://webcam.io/api/webcams/m7g61z" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: 22l7kIX0AwdMcdpo7v" \
-d '{
"dynamic_text1": "Temp: 23°C | Humidity: 65%",
"dynamic_text2": "Wind: 12 km/h NE",
"dynamic_text3": "Updated: 2025-01-13 14:30"
}'Configure Overlay Position
Text overlay position and styling is configured in the webcam.io dashboard:
- Go to Webcams → Edit → Text Overlays
- Add
{dynamic_text1},{dynamic_text2},{dynamic_text3}variables - Set position, font, color, background
See Text Overlays Documentation for details.
Enable/Disable Webcam
Control when your webcam captures images by setting the interval parameter.
Disable Webcam (Stop Capture)
Set interval to 0 to stop image collection:
curl -X PUT "https://webcam.io/api/webcams/m7g61z" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: 22l7kIX0AwdMcdpo7v" \
-d '{"interval": 0}'Enable Webcam (Start Capture)
Set interval to desired seconds (e.g., 60 = 1 minute):
curl -X PUT "https://webcam.io/api/webcams/m7g61z" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: 22l7kIX0AwdMcdpo7v" \
-d '{"interval": 60}'Common Intervals
| Interval (seconds) | Captures per Hour | Captures per Day |
|---|---|---|
| 15 | 240 | 5,760 |
| 30 | 120 | 2,880 |
| 60 | 60 | 1,440 |
| 300 | 12 | 288 |
| 900 | 4 | 96 |
Live Stream Control
Control live streaming settings programmatically.
Enable/Disable Streaming
# Enable streaming
curl -X PUT "https://webcam.io/api/webcams/m7g61z" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: 22l7kIX0AwdMcdpo7v" \
-d '{"stream_enabled": true}'
# Disable streaming
curl -X PUT "https://webcam.io/api/webcams/m7g61z" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: 22l7kIX0AwdMcdpo7v" \
-d '{"stream_enabled": false}'Change Stream Source/Destination
Update source (camera) and destination (YouTube/Twitch) URLs:
curl -X PUT "https://webcam.io/api/webcams/m7g61z" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: 22l7kIX0AwdMcdpo7v" \
-d '{
"stream_src_url": "rtsp://admin:pass@192.168.1.100:554/Streaming/Channels/101",
"stream_dest_url": "rtmp://a.rtmp.youtube.com/live2/xxxx-xxxx-xxxx-xxxx"
}'Control Backup Stream
curl -X PUT "https://webcam.io/api/webcams/m7g61z" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: 22l7kIX0AwdMcdpo7v" \
-d '{"backup_stream_enabled": true}'Code Examples
#!/bin/bash
# Update weather overlay every 10 minutes
API_EMAIL="user@example.com"
API_KEY="22l7kIX0AwdMcdpo7v"
WEBCAM_ID="m7g61z"
# Get weather data (example using wttr.in)
TEMP=$(curl -s "wttr.in/Berlin?format=%t")
HUMIDITY=$(curl -s "wttr.in/Berlin?format=%h")
WIND=$(curl -s "wttr.in/Berlin?format=%w")
# Update webcam overlay
curl -X PUT "https://webcam.io/api/webcams/$WEBCAM_ID" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: $API_EMAIL" \
-H "X-Auth-Key: $API_KEY" \
-d "{
\"dynamic_text1\": \"$TEMP | $HUMIDITY\",
\"dynamic_text2\": \"Wind: $WIND\"
}"import requests
import json
# Configuration
API_EMAIL = "user@example.com"
API_KEY = "22l7kIX0AwdMcdpo7v"
WEBCAM_ID = "m7g61z"
BASE_URL = f"https://webcam.io/api/webcams/{WEBCAM_ID}"
# Headers
headers = {
"Content-Type": "application/json",
"X-Auth-Email": API_EMAIL,
"X-Auth-Key": API_KEY
}
def update_overlay(text1=None, text2=None, text3=None):
"""Update dynamic text overlays."""
data = {}
if text1: data["dynamic_text1"] = text1
if text2: data["dynamic_text2"] = text2
if text3: data["dynamic_text3"] = text3
response = requests.put(BASE_URL, headers=headers, json=data)
return response.json()
def set_interval(seconds):
"""Enable/disable webcam by setting interval."""
response = requests.put(
BASE_URL,
headers=headers,
json={"interval": seconds}
)
return response.json()
def control_stream(enabled):
"""Enable or disable live streaming."""
response = requests.put(
BASE_URL,
headers=headers,
json={"stream_enabled": enabled}
)
return response.json()
# Examples
if __name__ == "__main__":
# Update overlay with weather
result = update_overlay(
text1="Temperature: 23°C",
text2="Humidity: 65%"
)
print(f"Update result: {result}")
# Disable webcam
# result = set_interval(0)
# Enable with 1-minute interval
# result = set_interval(60)
# Start streaming
# result = control_stream(True)// webcam.io API client
const API_EMAIL = 'user@example.com';
const API_KEY = '22l7kIX0AwdMcdpo7v';
const WEBCAM_ID = 'm7g61z';
const BASE_URL = `https://webcam.io/api/webcams/${WEBCAM_ID}`;
async function updateWebcam(params) {
const response = await fetch(BASE_URL, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-Auth-Email': API_EMAIL,
'X-Auth-Key': API_KEY
},
body: JSON.stringify(params)
});
return response.json();
}
// Update text overlay
async function updateOverlay(text1, text2 = null, text3 = null) {
const data = { dynamic_text1: text1 };
if (text2) data.dynamic_text2 = text2;
if (text3) data.dynamic_text3 = text3;
return updateWebcam(data);
}
// Enable/disable webcam
async function setInterval(seconds) {
return updateWebcam({ interval: seconds });
}
// Control streaming
async function setStreaming(enabled) {
return updateWebcam({ stream_enabled: enabled });
}
// Example usage
(async () => {
// Update overlay
const result = await updateOverlay(
'Temperature: 23°C',
'Wind: 12 km/h NE'
);
console.log('Update result:', result);
// Disable webcam
// await setInterval(0);
// Enable with 60s interval
// await setInterval(60);
})();<?php
// webcam.io API client
define('API_EMAIL', 'user@example.com');
define('API_KEY', '22l7kIX0AwdMcdpo7v');
define('WEBCAM_ID', 'm7g61z');
define('BASE_URL', 'https://webcam.io/api/webcams/' . WEBCAM_ID);
function updateWebcam($params) {
$ch = curl_init(BASE_URL);
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_POSTFIELDS => json_encode($params),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Auth-Email: ' . API_EMAIL,
'X-Auth-Key: ' . API_KEY
]
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
function updateOverlay($text1, $text2 = null, $text3 = null) {
$data = ['dynamic_text1' => $text1];
if ($text2) $data['dynamic_text2'] = $text2;
if ($text3) $data['dynamic_text3'] = $text3;
return updateWebcam($data);
}
function setInterval($seconds) {
return updateWebcam(['interval' => $seconds]);
}
function setStreaming($enabled) {
return updateWebcam(['stream_enabled' => $enabled]);
}
// Example usage
$result = updateOverlay(
'Temperature: 23°C',
'Humidity: 65%'
);
print_r($result);
// Disable webcam
// setInterval(0);
// Enable with 60s interval
// setInterval(60);
?>// webcam.io API client (Node.js with axios)
const axios = require('axios');
const config = {
email: 'user@example.com',
apiKey: '22l7kIX0AwdMcdpo7v',
webcamId: 'm7g61z'
};
const api = axios.create({
baseURL: 'https://webcam.io/api/webcams',
headers: {
'Content-Type': 'application/json',
'X-Auth-Email': config.email,
'X-Auth-Key': config.apiKey
}
});
async function updateWebcam(params) {
const response = await api.put(`/${config.webcamId}`, params);
return response.data;
}
// Update overlay with sensor data
async function updateFromSensor() {
// Example: Read from sensor (pseudo-code)
const temperature = 23.5;
const humidity = 65;
return updateWebcam({
dynamic_text1: `Temp: ${temperature}°C | Humidity: ${humidity}%`,
dynamic_text2: `Updated: ${new Date().toISOString()}`
});
}
// Schedule updates every 5 minutes
setInterval(updateFromSensor, 5 * 60 * 1000);
module.exports = { updateWebcam, updateFromSensor };Use Cases & Examples
Weather Station Integration
Display live weather data from a sensor or weather API:
#!/bin/bash
# weather-overlay.sh - Run via cron every 10 minutes
# Fetch weather from Open-Meteo API (free, no key needed)
WEATHER=$(curl -s "https://api.open-meteo.com/v1/forecast?latitude=52.52&longitude=13.41¤t_weather=true")
TEMP=$(echo $WEATHER | jq -r '.current_weather.temperature')
WIND=$(echo $WEATHER | jq -r '.current_weather.windspeed')
curl -X PUT "https://webcam.io/api/webcams/m7g61z" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: 22l7kIX0AwdMcdpo7v" \
-d "{\"dynamic_text1\": \"${TEMP}°C | Wind: ${WIND} km/h\"}"Cron entry (every 10 minutes):
*/10 * * * * /home/user/weather-overlay.sh
Scheduled Stream Control
Start streaming at 8 AM, stop at 6 PM:
# start-stream.sh (cron: 0 8 * * *)
curl -X PUT "https://webcam.io/api/webcams/m7g61z" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: 22l7kIX0AwdMcdpo7v" \
-d '{"stream_enabled": true}'
# stop-stream.sh (cron: 0 18 * * *)
curl -X PUT "https://webcam.io/api/webcams/m7g61z" \
-H "Content-Type: application/json" \
-H "X-Auth-Email: user@example.com" \
-H "X-Auth-Key: 22l7kIX0AwdMcdpo7v" \
-d '{"stream_enabled": false}'IoT Sensor Display (Raspberry Pi)
#!/usr/bin/env python3
# Read DHT22 sensor and update webcam overlay
import Adafruit_DHT
import requests
import time
SENSOR = Adafruit_DHT.DHT22
PIN = 4 # GPIO pin
API_EMAIL = "user@example.com"
API_KEY = "22l7kIX0AwdMcdpo7v"
WEBCAM_ID = "m7g61z"
def update_overlay(temp, humidity):
requests.put(
f"https://webcam.io/api/webcams/{WEBCAM_ID}",
headers={
"Content-Type": "application/json",
"X-Auth-Email": API_EMAIL,
"X-Auth-Key": API_KEY
},
json={
"dynamic_text1": f"Temp: {temp:.1f}°C",
"dynamic_text2": f"Humidity: {humidity:.1f}%"
}
)
while True:
humidity, temperature = Adafruit_DHT.read_retry(SENSOR, PIN)
if humidity and temperature:
update_overlay(temperature, humidity)
time.sleep(300) # Update every 5 minutesHome Assistant Integration
# configuration.yaml
rest_command:
webcam_overlay:
url: "https://webcam.io/api/webcams/m7g61z"
method: PUT
headers:
Content-Type: application/json
X-Auth-Email: "user@example.com"
X-Auth-Key: "22l7kIX0AwdMcdpo7v"
payload: '{"dynamic_text1": "{{ text }}"}'
# automations.yaml
- alias: "Update webcam with temperature"
trigger:
- platform: time_pattern
minutes: "/10"
action:
- service: rest_command.webcam_overlay
data:
text: "{{ states('sensor.outdoor_temperature') }}°C"Rate Limits
The API has rate limits to prevent abuse. Exceeding limits may temporarily lock your account.
Guidelines:
- Maximum 60 requests per hour per webcam
- Recommended: Update overlays every 5–10 minutes
- Avoid rapid consecutive calls
- Use batch updates (multiple parameters in one request)
If rate limited:
- Wait 1 hour before retrying
- Reduce update frequency
- Contact support if you need higher limits
Error Handling
Common Errors
| HTTP Code | Error | Solution |
|---|---|---|
| 401 | Invalid API key | Check X-Auth-Key header |
| 401 | Invalid email | Check X-Auth-Email header |
| 404 | Webcam not found | Verify WEBCAM-ID |
| 429 | Rate limit exceeded | Wait and reduce frequency |
| 500 | Server error | Retry after a few minutes |
Error Response Format
{
"error": "Error message description",
"code": 401
}Handling Errors (Python Example)
import requests
def update_webcam_safe(webcam_id, params):
try:
response = requests.put(
f"https://webcam.io/api/webcams/{webcam_id}",
headers={
"Content-Type": "application/json",
"X-Auth-Email": API_EMAIL,
"X-Auth-Key": API_KEY
},
json=params,
timeout=10
)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 429:
print("Rate limited - waiting before retry")
time.sleep(3600) # Wait 1 hour
else:
print(f"HTTP Error: {e}")
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
return NoneExternal Services
Don’t have your own server? Use these services to schedule API calls:
| Service | Free Tier | Notes |
|---|---|---|
| EasyCron | 200 calls/month | Simple UI, reliable |
| cron-job.org | Unlimited | Free, EU-based |
| Pipedream | 10,000 calls/month | Visual workflows |
| IFTTT | Limited | Good for simple triggers |
Next Steps
- Text Overlays — Configure overlay appearance
- Timer Settings — Built-in scheduling (no API needed)
- Monitoring — Get alerts for camera issues
- Contact Support — Questions about API usage
For enterprise use cases requiring higher API limits, contact us to discuss your requirements.