API Reference
Complete REST API documentation for TruthMark invisible watermarking service.
Base URL
https://truthmark-api.onrender.comFor local development: http://localhost:8000
Authentication
Include your API key in the X-API-Key header for all authenticated requests:
X-API-Key: tm_live_your_api_key_hereImportant: Free tier allows unauthenticated requests with lower rate limits (10 req/min). Paid plans require API key authentication for full rate limits and features.
/v1/encode
Embed an invisible watermark into an image. The watermark uses spread-spectrum DCT embedding with HKDF key derivation, AES-256 encryption, and Reed-Solomon error correction.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
file | multipart/form-data | Yes | Image file (PNG, JPG, JPEG). Min 256x256, max 10MB. |
message | string (form field) | Yes | Text payload to embed (max 500 characters). Supports UTF-8, JSON strings, etc. |
Example Request
curl -X POST https://truthmark-api.onrender.com/v1/encode \
-H "X-API-Key: tm_live_abc123" \
-F "file=@photo.png" \
-F "message=Copyright 2025 - My Company"Success Response 200 OK
{
"status": "success",
"metadata": {
"psnr": 42.5, // Peak signal-to-noise ratio (higher = better quality)
"bits_embedded": 256 // Number of data bits embedded
},
"download_url": "https://truthmark-api.onrender.com/download/wm_abc123.png",
"filename": "truthmark-protected.png"
}/v1/decode
Extract a hidden watermark from an image. Returns the embedded message and a confidence score indicating extraction reliability.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
file | multipart/form-data | Yes | Possibly watermarked image file (PNG, JPG, JPEG) |
Example Request
curl -X POST https://truthmark-api.onrender.com/v1/decode \
-H "X-API-Key: tm_live_abc123" \
-F "file=@watermarked.png"Response — Watermark Found 200 OK
{
"found": true,
"message": "Copyright 2025 - My Company",
"confidence": 0.95 // 0.0 to 1.0 — higher is more reliable
}Response — No Watermark
{
"found": false,
"message": null,
"confidence": 0.0
}Quick Examples by Language
Python (requests)
import requests
BASE = "https://truthmark-api.onrender.com"
HEADERS = {"X-API-Key": "tm_live_abc123"}
# Encode
with open("photo.png", "rb") as f:
r = requests.post(f"{BASE}/v1/encode",
headers=HEADERS,
files={"file": f},
data={"message": "© 2025 MyCompany"})
print(r.json()["download_url"])
# Decode
with open("watermarked.png", "rb") as f:
r = requests.post(f"{BASE}/v1/decode",
headers=HEADERS, files={"file": f})
print(r.json())JavaScript (fetch)
const BASE = "https://truthmark-api.onrender.com";
// Encode
const form = new FormData();
form.append("file", fileInput.files[0]);
form.append("message", "© 2025 MyCompany");
const res = await fetch(`${BASE}/v1/encode`, {
method: "POST",
headers: { "X-API-Key": "tm_live_abc123" },
body: form,
});
const { download_url } = await res.json();
// Decode
const decodeForm = new FormData();
decodeForm.append("file", watermarkedFile);
const decoded = await fetch(`${BASE}/v1/decode`, {
method: "POST",
headers: { "X-API-Key": "tm_live_abc123" },
body: decodeForm,
}).then(r => r.json());Error Handling
All errors return appropriate HTTP status codes with a JSON error body:
{
"detail": "Error message description"
}Status Codes
| Code | Meaning | Resolution |
|---|---|---|
200 | Success | Request processed successfully |
400 | Bad Request | Check file format (PNG/JPG only) and message length (≤ 500 chars) |
401 | Unauthorized | Verify your API key in X-API-Key header |
413 | Payload Too Large | Image exceeds 10MB limit |
429 | Rate Limited | Wait and retry. Check Retry-After header. |
500 | Server Error | Retry request. If persistent, contact support. |
Rate Limits
Rate limits are enforced per API key. Exceeding the limit returns 429.
| Plan | Requests/Minute | Images/Month |
|---|---|---|
| Free | 10 | 100 |
| Starter | 60 | 2,500 (+ overage at $0.008/img) |
| Professional | 300 | 25,000 (+ overage at $0.004/img) |
| Enterprise | Custom | Unlimited |
Best Practices
Use images ≥ 512x512 pixels
Larger images provide more frequency-domain capacity, resulting in higher PSNR and better extraction confidence.
Keep messages under 200 characters
Shorter payloads embed more redundantly and extract more reliably. Use JSON for structured data.
Check confidence scores
Only trust decoded messages with confidence > 0.7. Lower scores may indicate image degradation.
Use PNG for maximum quality
PNG is lossless — encoding into PNG yields the highest PSNR. JPEG is supported but introduces minor quality reduction.
Start Building
Choose your SDK and start embedding watermarks in minutes.