API Reference
The ProofMark REST API lets you create, manage, and verify digital product passports at scale — from single products to batches of 1,000+.
Overview
All API requests use JSON. Responses always include a success boolean field. On failure, a message field describes the error.
https://proofmark-8ww4.polsia.app
Authentication
All write endpoints and admin read endpoints require a valid session token obtained via the admin login. Pass the token as a cookie (pm_auth) or as a Bearer token in the Authorization header.
Authorization: Bearer <your-token>
Obtain a Token
Submit your admin password to receive a session token (valid 7 days). The token is also set as an httpOnly cookie automatically.
{
"password": "your-admin-password"
}
{
"success": true
}
Create Passport
Creates a passport with a unique PM-XXXXXXXX ID and automatically generates a QR code pointing to the public verification page.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| product_name | string | required | Name of the product |
| materials | string[] | optional | Array of material names (e.g. ["Organic Cotton", "Recycled Polyester"]) |
| origin | string | optional | Country or region of manufacture |
| manufacturer | string | optional | Manufacturer name |
| dpp_status | string | optional | DPP compliance status. Default: "compliant" |
| sustainability_score | string | optional | Sustainability rating A–F. Default: "A" |
| batch_id | string | optional | Batch or lot identifier for grouping |
| metadata | object | optional | Custom key-value data |
curl -X POST https://proofmark-8ww4.polsia.app/api/passports \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "product_name": "Luxury Tote Bag", "materials": ["Full-Grain Leather", "Brass Hardware"], "origin": "Italy", "manufacturer": "Atelier Milano", "dpp_status": "compliant", "sustainability_score": "B", "batch_id": "BATCH-2026-Q1" }'
{
"success": true,
"passport": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"passport_id": "PM-A3F81C2B",
"product_name": "Luxury Tote Bag",
"materials": ["Full-Grain Leather", "Brass Hardware"],
"origin": "Italy",
"manufacturer": "Atelier Milano",
"dpp_status": "compliant",
"sustainability_score": "B",
"batch_id": "BATCH-2026-Q1",
"qr_code": "data:image/png;base64,...",
"verify_url": "https://proofmark-8ww4.polsia.app/verify/PM-A3F81C2B",
"created_at": "2026-03-17T10:50:00Z"
}
}
List Passports
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| search | string | Search by product name, passport ID, or manufacturer |
| batch_id | string | Filter by batch ID |
| limit | integer | Max results per page (default: 50, max: 1000) |
| offset | integer | Pagination offset (default: 0) |
{
"success": true,
"passports": [ /* array of passport objects */ ],
"total": 142,
"limit": 50,
"offset": 0
}
Get Passport
Retrieve a passport by its passport_id (e.g. PM-A3F81C2B) or internal UUID.
curl https://proofmark-8ww4.polsia.app/api/passports/PM-A3F81C2B \ -H "Authorization: Bearer <token>"
Update Passport
Partial updates — only include fields you want to change. All fields from Create Passport are accepted except passport_id (immutable).
curl -X PATCH https://proofmark-8ww4.polsia.app/api/passports/PM-A3F81C2B \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "sustainability_score": "A" }'
Delete Passport
This action is irreversible. The QR code will stop resolving to a valid verification page.
{ "success": true, "message": "Passport deleted" }
Download QR Code
Returns a PNG image for download. The QR code encodes the public verification URL for that passport.
| Parameter | Description |
|---|---|
| ?size | Image size in pixels (50–600). Default: 400 |
curl -o PM-A3F81C2B-qr.png \ "https://proofmark-8ww4.polsia.app/api/passports/PM-A3F81C2B/qr?size=400" \ -H "Authorization: Bearer <token>"
Bulk QR Export
Returns a ZIP archive containing one PNG per passport. Supports up to 1,000 QR codes per request.
| Parameter | Description |
|---|---|
| ?ids | Comma-separated list of passport IDs. Omit to export all. |
| ?batch_id | Export all passports in a batch. |
# Export specific passports curl -o qr-codes.zip \ "https://proofmark-8ww4.polsia.app/api/passports/qr/bulk?ids=PM-A3F81C2B,PM-B4C92D3E" \ -H "Authorization: Bearer <token>" # Export entire batch curl -o qr-codes.zip \ "https://proofmark-8ww4.polsia.app/api/passports/qr/bulk?batch_id=BATCH-2026-Q1" \ -H "Authorization: Bearer <token>"
Import Passports
Import passports from a CSV file or JSON array. QR codes are auto-generated for all imported passports.
CSV Format
First row must be a header row with column names matching the passport fields.
product_name,materials,origin,manufacturer,dpp_status,sustainability_score,batch_id Leather Wallet,"Full-Grain Leather,Cotton Lining",Italy,Atelier Milano,compliant,A,BATCH-Q1 Canvas Tote,"Organic Cotton,Brass Hardware",Portugal,Porto Fabrics,compliant,B,BATCH-Q1
JSON Format
curl -X POST https://proofmark-8ww4.polsia.app/api/passports/import \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "passports": [{ "product_name": "Sneaker", "origin": "Portugal" }] }'
{
"success": true,
"imported": 250,
"failed": 0,
"passports": [ /* array of created passport objects */ ]
}
Stats Overview
{
"success": true,
"stats": {
"total_passports": 1420,
"compliant": 1380,
"recent_7d": 84
}
}
Verify Product
This is the URL encoded in every QR code. Returns a branded HTML verification page showing product details, materials, DPP status, and sustainability score.
https://proofmark-8ww4.polsia.app/verify/PM-A3F81C2B
Capture Lead
Used by the ProofMark landing page. Deduplicates by email. Triggers an email notification to the admin.
{
"email": "brand@example.com",
"company_name": "Atelier Milano",
"source": "landing"
}
Passport Object Schema
The full passport object returned by create, get, and list endpoints.
PM-XXXXXXXX. Auto-generated. Immutable.
compliant, pending, non-compliant.
Error Codes
All errors return a success: false response with a human-readable message.
| Status | Description |
|---|---|
| 400 Bad Request | Missing required fields (e.g. product_name not provided) |
| 401 Unauthorized | Missing or invalid authentication token |
| 404 Not Found | Passport ID does not exist |
| 429 Too Many Requests | Rate limit exceeded (import endpoint caps at 1,000 records) |
| 500 Internal Server Error | Unexpected server error |
Shopify Integration
Auto-create a ProofMark passport whenever a new product is added in Shopify using Shopify Webhooks.
// In your Shopify app or webhook handler: app.post('/webhooks/shopify/product-created', async (req, res) => { const product = req.body; const response = await fetch('https://proofmark-8ww4.polsia.app/api/passports', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.PROOFMARK_TOKEN}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ product_name: product.title, materials: product.tags?.split(',') || [], origin: product.vendor, metadata: { shopify_product_id: product.id, shopify_handle: product.handle } }) }); const passport = await response.json(); // Store passport.passport.verify_url in your product metafields // Print passport.passport.qr_code to packaging res.json({ success: true }); });
WooCommerce Integration
Use WooCommerce's product save hooks to create passports automatically.
add_action('woocommerce_new_product', 'create_proofmark_passport'); function create_proofmark_passport($product_id) { $product = wc_get_product($product_id); $response = wp_remote_post('https://proofmark-8ww4.polsia.app/api/passports', [ 'headers' => [ 'Authorization' => 'Bearer ' . get_option('proofmark_api_token'), 'Content-Type' => 'application/json' ], 'body' => json_encode([ 'product_name' => $product->get_name(), 'manufacturer' => $product->get_attribute('manufacturer'), 'origin' => $product->get_attribute('origin'), 'metadata' => ['woo_id' => $product_id] ]) ]); $passport = json_decode(wp_remote_retrieve_body($response)); update_post_meta($product_id, '_proofmark_passport_id', $passport->passport->passport_id); update_post_meta($product_id, '_proofmark_verify_url', $passport->passport->verify_url); }
ERP / Bulk Import
For large product catalogs, use the bulk import endpoint with a CSV export from your ERP or PIM system.
import requests import csv TOKEN = "your-proofmark-token" BASE = "https://proofmark-8ww4.polsia.app" # Load product data from ERP export with open("products.csv") as f: reader = csv.DictReader(f) products = list(reader) # Send in batches of 1,000 for i in range(0, len(products), 1000): batch = products[i:i+1000] res = requests.post( f"{BASE}/api/passports/import", headers={"Authorization": f"Bearer {TOKEN}"}, json={"passports": batch} ) data = res.json() print(f"Batch {i//1000 + 1}: imported {data['imported']}, failed {data['failed']}")
Ready to get started?
Create your first product passport in seconds. No hardware required.
Start Free Trial →