Digital Soul
Digital Soul
Open API · v1
Integrate Digital Soul’s permanent provenance and on-chain loyalty system into your brand ecosystem. All endpoints return JSON. Authentication is cookie-based for admin routes, or requires soul ownership for customer-facing routes.
Base URL
https://api.digitalsoul.io/v1
Authentication
Admin endpoints require a cookie-based session token. Obtain via POST /api/admin/auth with { password }. The session cookie admin_session is automatically set and valid for 24 hours.
Rate limits: 60 requests/minute per IP. Admin endpoints: 10 auth attempts per 15 minutes.
Retrieve and interact with Digital Soul objects. Each soul represents a physical luxury item with permanent on-chain identity.
Query loyalty data, tiers, and redemption history for soul owners.
GPS-verified in-store check-ins that award loyalty points and trigger webhook events.
Receive real-time events for soul activity. All payloads are HMAC-SHA256 signed with your webhook secret.
Access the complete brand collection catalogue.
Protected endpoints for minting souls, updating statuses, and sending claim invitations. All admin endpoints require a valid admin_session cookie obtained via POST /api/admin/auth.
Token-based flow for customers to claim ownership of a soul sent to them via a claim invitation email.
Secondary market data for Digital Soul tokens, powered by Reservoir (aggregates OpenSea, Blur, and LooksRare). Only populated once the soul's contract is deployed to mainnet.
EU Digital Product Passport (DPP) — public endpoint returning structured data conforming to EU Regulation 2024/1781 (ESPR). Machine-readable for compliance tooling.
In-app notification feed and Expo push token management. Notifications are triggered automatically by claims, tier upgrades, anniversaries, new rewards, and transfers.
All webhook payloads are signed with HMAC-SHA256 using your webhook secret. Verify the signature before processing any event.
Signature Verification (Node.js)
import crypto from "crypto";
function verifyWebhookSignature(
payload: string,
signature: string,
secret: string
): boolean {
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature, "hex"),
Buffer.from(expected, "hex")
);
}
// In your webhook handler:
app.post("/webhooks/digital-soul", (req, res) => {
const sig = req.headers["x-digital-soul-signature"];
const raw = JSON.stringify(req.body);
if (!verifyWebhookSignature(raw, sig, process.env.WEBHOOK_SECRET)) {
return res.status(401).json({ error: "Invalid signature" });
}
const { event, data, timestamp } = req.body;
// Process event...
res.json({ received: true });
});Payload Shape
{
"event": "soul.claimed",
"timestamp": "2026-04-07T10:30:00Z",
"data": {
"soulId": "soul-002",
"ownerEmail": "owner@example.com",
"brand": "Your Brand"
}
}Verify signatures using the X-DigitalSoul-Signature: sha256=... header. Compute HMAC-SHA256(body, your_secret) and compare using a timing-safe equality check.