Introduction

SPATEMO API

SPATEMO is the infrastructure layer for the physical web. Register any real-world object as an EMO — an Executable Media Object — and it becomes detectable, interactive, and royalty-bearing across every camera surface, with no QR code, no app install, and no modification to the object itself.

This reference covers the full API: registering and managing EMOs, querying the detection endpoint, reading the royalty ledger, and receiving event webhooks.

Access is invite-only during the private beta. Submit your use case at the Developer Portal — credentials are issued within 24 hours of approval.

Base URL

https://spatemo.com/v1

Versioning

The API is versioned via the URL path. The current stable version is v1. Breaking changes will be introduced under a new version prefix with at least 90 days notice.

Getting Started

Authentication

All requests must include a bearer token issued to your account. Tokens are prefixed spat_live_ for production and spat_test_ for the sandbox environment.

# Every request requires this header
Authorization: Bearer spat_live_••••••••••••••••

Keep your API key secret. Do not expose it in client-side code, public repositories, or build logs. If a key is compromised, rotate it immediately from the Developer Portal — the old key is invalidated within 60 seconds.

Test vs. Live keys

Prefix Environment Behavior
spat_test_ Sandbox Recognition runs against test EMOs only. No ledger settlements. No charges.
spat_live_ Production Full detection against registered EMOs. Ledger settlements are real.
Getting Started

Quickstart

Register your first EMO and make it detectable in three steps.

1. Register an EMO

POST a reference image and your desired CTA configuration. SPATEMO extracts visual fingerprints and returns a unique EMO ID.

curl -X POST https://spatemo.com/v1/emos \
  -H "Authorization: Bearer spat_live_..." \
  -H "Content-Type: multipart/form-data" \
  -F "name=CR7 Jersey" \
  -F "image=@cr7_jersey.jpg" \
  -F "ctaLabel=Buy Now" \
  -F "buyUrl=https://nike.com/cr7"
// Response
{
  "id":         "emo_1a2b3c4d",
  "name":       "CR7 Jersey",
  "status":     "indexing",
  "ctaLabel":   "Buy Now",
  "buyUrl":     "https://nike.com/cr7",
  "createdAt":  "2026-06-26T14:22:00Z"
}

Indexing typically completes in under 30 seconds. Poll GET /v1/emos/{id} until status is "active" before sending detection requests.

2. Send a detection request

From any camera surface — web, native, or wearable — POST a frame or image crop to the detection endpoint. SPATEMO returns the matched EMO and its CTA payload.

curl -X POST https://spatemo.com/v1/detect \
  -H "Authorization: Bearer spat_live_..." \
  -H "Content-Type: multipart/form-data" \
  -F "image=@camera_frame.jpg" \
  -F "sessionId=usr_session_xyz"
// Response — match found
{
  "matched":    true,
  "emoId":      "emo_1a2b3c4d",
  "confidence": 0.97,
  "cta": {
    "label":    "Buy Now",
    "url":      "https://nike.com/cr7"
  },
  "detectionId": "det_9z8y7x"
}

3. Handle the CTA in your UI

Use the cta payload to render whatever experience makes sense for your surface — an overlay, a push notification, a native sheet. The detectionId is recorded in the royalty ledger automatically.

Core Concepts

EMOs

An EMO — Executable Media Object — is SPATEMO's fundamental unit. It's the binding between a physical object in the real world and a digital address on the internet. Once registered, every instance of that object anywhere in the world shares the same address.

What makes a good EMO candidate

SPATEMO's recognition is visual-fingerprint based, so the object should have consistent, distinctive visual characteristics. Objects that work well:

Object typeWhy it works
Consumer product packagingConsistent print across millions of units. Highly distinctive label art.
Sports jerseys & merchandiseUnique number/logo combinations. High-contrast graphics.
Event tickets & lanyardsPrinted designs with sparse, identifiable patterns.
Branded apparelLogo patches, tags, and print treatments.
Trading cards & collectiblesDense visual information with high per-card uniqueness.

EMO status lifecycle

StatusMeaning
indexingReference image received. Visual fingerprint extraction in progress.
activeEMO is live. Detection requests will match against it.
pausedTemporarily removed from the detection index. No matches will fire.
archivedPermanently removed. Historical detections remain in the ledger.

Reference image guidelines

Supply the highest-quality reference image available. SPATEMO will normalize it, but better input produces more reliable detections.

Core Concepts

Recognition

When a camera frame is submitted to POST /v1/detect, SPATEMO computes a visual fingerprint from the frame and queries the index for the nearest registered EMO. If the confidence score exceeds the threshold, a match is returned.

Confidence threshold

By default, SPATEMO returns a match only when confidence is ≥ 0.90. You can lower this threshold per-request using the minConfidence parameter, but values below 0.75 will produce a higher false-positive rate.

No-match response

{
  "matched":   false,
  "candidates": []
}

A no-match response means no registered EMO was found above the threshold. The frame is not stored.

Session IDs

Passing a sessionId with detection requests groups multiple detections from the same user session. This is used for deduplication in the royalty ledger — a single user encountering the same EMO repeatedly in one session counts as one billable detection event by default.

Session IDs should be opaque identifiers — do not use PII (names, emails, device IDs) as session values. Use a random UUID generated per session.

Core Concepts

Royalty Ledger

Every confirmed detection event that results in a CTA action is recorded in the SPATEMO royalty ledger. Revenue is split automatically among four parties.

20%
Object owner / rights holder
50%
Camera platform / developer
20%
End user / detector
10%
SPATEMO infrastructure

Settlement

Ledger balances are settled monthly to registered payout accounts. Minimum payout threshold is $25. Balances below the threshold roll forward to the next cycle.

Ledger events

Every detection that results in a CTA action creates a detection.converted ledger event. Use GET /v1/ledger to query your account's events and aggregate earnings.

Ledger entries are immutable. Once a detection event is recorded, it cannot be modified or deleted. Disputed events are flagged and reviewed, but the original record is preserved.

API Reference

EMO Endpoints

Register an EMO

POST /v1/emos

Create a new EMO by supplying a reference image and CTA configuration. The object is indexed asynchronously — poll status until active.

Request parameters

ParameterTypeRequiredDescription
namestringYesHuman-readable label for this EMO.
imagefileYesReference image (JPEG / PNG / WebP, min 800px).
ctaLabelstringYesButton text shown to the end user on detection.
buyUrlstringYesDestination URL triggered when CTA is tapped.
additionalImagesfile[]NoUp to 4 supplemental reference images for multi-angle coverage.
metadataobjectNoArbitrary key-value pairs stored with the EMO (max 2KB).

Retrieve an EMO

GET /v1/emos/{id}
curl https://spatemo.com/v1/emos/emo_1a2b3c4d \
  -H "Authorization: Bearer spat_live_..."

List EMOs

GET /v1/emos

Returns a paginated list of your registered EMOs. Supports status filtering and cursor-based pagination via after.

Query paramDefaultDescription
statusFilter by status: indexing, active, paused, archived.
limit20Results per page. Max 100.
afterCursor for the next page (from pagination.next in prior response).

Update an EMO

POST /v1/emos/{id}

Update name, ctaLabel, buyUrl, status, or metadata. Reference images cannot be changed — archive and re-register to update the visual fingerprint.

Archive an EMO

DELETE /v1/emos/{id}

Sets the EMO status to archived. It is removed from the detection index within 60 seconds. Ledger history is preserved.

API Reference

Detection Endpoint

POST /v1/detect

Submit an image frame for recognition. SPATEMO checks the frame against your active EMO index and returns the highest-confidence match above the threshold.

This endpoint is rate-limited by default to 60 requests/minute per API key. For high-frequency video streams, contact api@spatemo.com to discuss stream-optimized integration.

Request parameters

ParameterTypeRequiredDescription
imagefileYesCamera frame or image crop. JPEG / PNG / WebP.
sessionIdstringRecommendedOpaque per-session identifier for deduplication.
minConfidencefloatNoMinimum confidence score to return a match. Default: 0.90. Range: 0.501.00.
scopeEmoIdsstring[]NoLimit detection to a specific subset of your EMOs.

Response fields

FieldTypeDescription
matchedbooleanWhether a match was found above the confidence threshold.
emoIdstringID of the matched EMO. Present when matched is true.
confidencefloatMatch confidence score between 0 and 1.
ctaobjectCTA payload (label, url) from the matched EMO.
detectionIdstringUnique ID for this detection event. Logged in the royalty ledger.
latencyMsintegerServer-side processing time in milliseconds.
API Reference

Ledger Endpoint

GET /v1/ledger

Query your royalty ledger. Returns a paginated list of detection events that resulted in CTA conversions, with per-event and aggregate earnings.

Query parameters

ParameterDescription
emoIdFilter events for a specific EMO.
fromISO 8601 datetime. Start of query window.
toISO 8601 datetime. End of query window.
limitResults per page. Default 50, max 500.
// Example response
{
  "balance": {
    "pending":   142.50,
    "currency":  "USD"
  },
  "events": [
    {
      "detectionId": "det_9z8y7x",
      "emoId":       "emo_1a2b3c4d",
      "earnings":    0.42,
      "role":        "platform",
      "timestamp":   "2026-06-26T14:22:00Z"
    }
  ],
  "pagination": {
    "total": 1204,
    "next":  "cur_abc123"
  }
}
API Reference

Webhooks

Register a webhook URL to receive real-time event notifications. SPATEMO will POST a signed JSON payload to your endpoint when events occur.

Registering a webhook

curl -X POST https://spatemo.com/v1/webhooks \
  -H "Authorization: Bearer spat_live_..." \
  -H "Content-Type: application/json" \
  -d '{"url":"https://yourapp.com/hooks/spatemo","events":["detection.matched","detection.converted"]}'

Event types

EventFired when
emo.activeAn EMO finishes indexing and is ready for detection.
detection.matchedA detection request returns a match.
detection.convertedA matched CTA was acted upon by the end user.
ledger.settledMonthly ledger settlement is complete.

Verifying signatures

Each webhook request includes a Spatemo-Signature header containing an HMAC-SHA256 signature of the raw request body, signed with your webhook secret. Always verify this before processing.

// Node.js verification example
const crypto = require('crypto');

function verifyWebhook(rawBody, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  );
}
Resources

Error Codes

SPATEMO uses conventional HTTP status codes. Error responses include a machine-readable code and a human-readable message.

{
  "error": {
    "code":    "emo_not_found",
    "message": "No EMO found with the provided ID.",
    "status":  404
  }
}
CodeHTTPMeaning
unauthorized401Missing or invalid API key.
forbidden403Key does not have permission for this operation.
emo_not_found404No EMO with the provided ID exists in your account.
emo_not_active409Detection requested against an EMO that is not yet active.
image_too_small422Submitted image is below the 800px minimum dimension.
image_unreadable422Image could not be decoded. Check format and file integrity.
confidence_below_threshold200Not an error — match exists but confidence did not meet threshold. Returned as matched: false.
rate_limit_exceeded429You have exceeded the rate limit for this endpoint.
internal_error500Something went wrong on our end. Contact api@spatemo.com with the request ID.
Resources

Rate Limits

Limits are enforced per API key. Responses include rate limit headers on every request.

EndpointDefault limit
POST /v1/detect60 requests / minute
POST /v1/emos100 requests / hour
GET /v1/emos300 requests / minute
GET /v1/ledger60 requests / minute
# Rate limit headers included in all responses
X-RateLimit-Limit:     60
X-RateLimit-Remaining: 42
X-RateLimit-Reset:     1751234567

When a limit is exceeded, a 429 is returned with a Retry-After header indicating seconds until the window resets. Need higher limits? Contact api@spatemo.com.

Resources

Changelog

v1.0 — June 2026

Initial private beta release. EMO registration, detection, royalty ledger, and webhook endpoints available to approved developers.