InstantHero · API
API reference
Upload once, issue a unique URL for each email, and read image-load analytics with your metadata.
Authentication
Management and send requests require x-api-key or Authorization: Bearer YOUR_API_KEY. Keep the key on your server. Only unguessable tracking URLs are public.
Base URL: https://email.instanthero.ca
API prefix: /api/public/v1
x-api-key: YOUR_API_KEYUpload an image
POST /api/public/v1/assets accepts multipart form data with a file field. PNG, JPEG, GIF, or WebP; up to 10 MB. Images stay private.
curl -X POST "https://email.instanthero.ca/api/public/v1/assets" \
-H "x-api-key: $TRACKER_API_KEY" \
-F "file=@./banner.png"201 returns id, name, content_type, size_bytes, archived, created_at, and base_request_url. Use the returned UUID in subsequent requests.
Issue a tracking link
Every POST /api/public/v1/assets/:id/links creates a fresh URL. Metadata is an arbitrary JSON object up to 32 KB. Each tracking URL ends in the image's file extension (for example .jpg or .png), which some email clients prefer.
curl -X POST "https://email.instanthero.ca/api/public/v1/assets/YOUR_ASSET_UUID/links" \
-H "x-api-key: $TRACKER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"metadata":{"recipient":"reader@example.com","campaign":"fall","custom":{"source":"crm"}}}'{
"id": "UNIQUE_TAG",
"asset_id": "YOUR_ASSET_UUID",
"metadata": {
"campaign": "fall"
},
"tracking_url": "https://email.instanthero.ca/api/public/t/UNIQUE_TAG.jpg",
"tag": "<img src=\"https://email.instanthero.ca/api/public/t/UNIQUE_TAG.jpg\" alt=\"\" />",
"created_at": "2026-10-21T23:40:00Z"
}The /links address is a POST endpoint, not an image URL: opening it in a browser returns 405 with instructions. Include your API key and JSON body, then load the returned tracking_url or insert the returned tag into email HTML. Loading the tracking URL yourself also counts. Add ?w=300 (1–2000) to any tracking URL to serve the image resized to that width in pixels; the resized load is tracked the same way.
Image library & analytics
GET /api/public/v1/assets | Library, link counts, load totals, and base request URLs. |
GET /api/public/v1/assets/:id | Details, metadata, and links with total_opens, last_opened_at, and latest 100 views each. |
GET /api/public/v1/assets/:id?preview=1 | Authenticated image bytes; does not count as an open. |
PATCH /api/public/v1/assets/:id | Rename or archive: {"name":"Banner","archived":true}. |
Archiving blocks new links and sends using that image; existing tracking URLs keep working. Views contain time, IP, and user agent.
Send with Gmail
POST /api/public/v1/send sends from the connected Gmail account. Supply one to address, subject, and html. Optional images references up to 50 uploaded images; each gets a fresh link.
curl -X POST "https://email.instanthero.ca/api/public/v1/send" \
-H "x-api-key: $TRACKER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to":"reader@example.com",
"subject":"Your update",
"html":"<html><body><h1>Your update</h1>{{image:0}}</body></html>",
"metadata":{"recipient":"reader@example.com","campaign":"fall"},
"images":[{"asset_id":"YOUR_ASSET_UUID","width":600,"metadata":{"placement":"banner"}}]
}'Use {{image:0}} for the first image, {{image:1}} for the second. Images with no placeholder are appended before the closing body tag. Existing image URLs are unchanged. Already-issued tags can be placed directly in HTML with images omitted. Optional per-image width (1–2000 px) serves resized bytes and sets the display width in the tag.
Top-level metadata merges into every new link; image metadata wins on matching keys. Subject: up to 500 characters. HTML: up to 500,000 characters. Each metadata object: 32 KB. 200 returns message_id, thread_id, and images containing id, asset_id, metadata, tracking_url, and tag. Read analytics using each asset_id.
Gmail acceptance is not confirmed delivery. Links are persisted before dispatch, so a rejected send may leave unused links. There is no automatic retry or duplicate-send protection. Check Gmail Sent before retrying an unconfirmed request.
Template library
Manage templates from the template library. GET /api/public/v1/templates lists saved templates. POST creates one; PATCH /api/public/v1/templates/:id updates it and DELETE removes it. Fields: name, subject, html, images. Read a template and pass its subject, html, and images to the send endpoint with your recipient and metadata.
{
"name": "Monthly update",
"subject": "Your update",
"html": "<h1>Your update</h1>{{image:0}}",
"images": [
{
"asset_id": "YOUR_ASSET_UUID"
}
]
}Errors & tracking limits
- 400: invalid fields or image. 401: incorrect tracker key. 404: missing or archived image. 413: upload too large. 500: preparation failure. 502: unconfirmed Gmail delivery. 503: Gmail not connected.
- Gmail rejections retain the provider's status and include provider_status and provider_body. Gmail quotas and account policies apply.
- Image loads are not confirmed human opens: blocking, caching, proxies, and prefetching affect counts. Multiple images can load for one email open. IP and user agent may belong to a proxy.
- Keep sensitive data out of metadata and follow applicable privacy and consent requirements.