Brand Seal public API

Embed hoarding QR codes and partner apps — verified seller payload without scraping the portal.

GET hoarding payload

GET /api/public/brand-seal/{sealId}

200 OK
{
  "version": "1",
  "sealId": "UN-SEAL-0003-K7M2",
  "tradeName": "Kapoor & Co. Realtors",
  "verifyUrl": "https://yoursite/seal/UN-SEAL-0003-K7M2",
  "liveListings": 3,
  "sampleListingCodes": ["UN1003", "..."]
}

Example: /api/public/brand-seal/UN-SEAL-0003-K7M2

Payment webhook

# Demo
POST /api/webhooks/payment
Header: x-uneed-webhook-secret: demo_webhook_secret
{ "intentId": "ti...", "event": "payment.captured", "paymentRef": "pay_xxx" }

# Production (Razorpay)
Header: X-Razorpay-Signature: <hmac sha256 of raw body>
Env: RAZORPAY_WEBHOOK_SECRET=<dashboard secret>
{ "event": "payment.captured", "payload": { "payment": { "entity": {
  "id": "pay_xxx",
  "notes": { "intentId": "ti..." }
}}}}

Captures only when Token intent is cleared and seal still valid. Rejected captures enqueue buyer SMS + WhatsApp template rows.

Partner CRM — lead webhook

POST /api/partner/crm-export
Authorization: session cookie (broker desk)
Body: { "leadIds": ["lead_demo1"] }  // optional — default last 25

Demo response includes full JSON payload + delivery log.
Prod: uneed POSTs to your saved webhook with header:
  X-Uneed-Signature: sha256=<hmac of body, CRM secret>

PATCH /api/partner/crm-settings
{ "webhookUrl": "https://your-crm.example/hooks/uneed" }

Configure on Partner desk → CRM. Bulk inventory: CSV upload.

Trust SMS & WhatsApp (demo log)

Flyer mismatch, blocked token intents, and blocked payments enqueue trustAlerts on both sms and whatsapp channels — visible in Management. Templates: uneed_seal_alert_sms_v1, uneed_seal_mismatch_wa_v1.

Hoarding print layout — portal-style board with Brand Seal QR.

Token payment (Razorpay)

POST /api/payments/razorpay-order
{ "intentId": "ti..." }

Env (live):
RAZORPAY_KEY_ID / RAZORPAY_KEY_SECRET
NEXT_PUBLIC_RAZORPAY_KEY_ID (Checkout UI)

META_WHATSAPP_TOKEN / META_WHATSAPP_PHONE_ID (optional send)

POST /api/payments/razorpay-verify
{ intentId, razorpay_order_id, razorpay_payment_id, razorpay_signature }

DLT_SMS_API_KEY / DLT_SENDER_ID / DLT_TEMPLATE_ID (optional SMS send)

Trademark pre-check

GET /api/trademark/lookup?tradeName=...&legalName=...

Demo watchlist + IPIndia stub — wire production TM API on same route.

Signed photo export (CDN demo)

GET /api/listings/{id}/export-token
→ { token, photoFingerprint, exportPipelineVersion }

Env: EXPORT_SIGNING_SECRET, EXPORT_CDN_BASE