POS, OMS & ERP Integration
Wire the systems you already run — your point-of-sale, order-management, and ERP — into SocialHub loyalty. Configure a managed connector for SAP, Dynamics 365, Manhattan Active Omni, IBM Sterling or Salesforce in-app — or integrate any other system through the same governed v2 REST API, authenticated with a tenant key, scoped per endpoint, and audited on every call.
One API, three system types
Every integration below is the v2 REST API over HTTPS with a Authorization: Bearer fl_live_… tenant key. Use a read-only key for reconciliation and a write-scoped key only where you award points or redeem coupons. For e-commerce platforms (Shopify, Amazon, TikTok Shop) prefer the native channel connectors — this guide is for systems without one.
Point of sale
Turn an in-store purchase into loyalty value: award points on the sale and redeem coupons at the register.
OMSOrder management
Let online & omnichannel orders earn — and returns claw back — keyed to your order ids.
ERPEnterprise resource planning
Push your store & member master (upsert by your externalId) and reconcile incrementally with your system of record.
Managed connectors
For five enterprise systems you don't write the integration at all — configure a connection in Settings → Data Sources(endpoint + encrypted credentials), verify it, and run a dry-run. Each connector normalizes the vendor's orders, customers and products and lands them through the very same API documented below — same scopes, same idempotency, same governed pipe. Each is labeled with how far it has been validated.
Salesforce — CRM / OMS
Fixture-validatedOrder / ReturnOrder / Account-Contact / Product2 via REST + SOQL; client-credentials OAuth.
SAP S/4HANA — ERP
Fixture-validatedSales order / business partner / product master via the OData A2X services; BTP OAuth.
Dynamics 365 — ERP / CRM
Fixture-validatedDataverse (CE) validated; Finance & Operations scaffolded. Entra ID OAuth.
Manhattan Active Omni — OMS
In design-partner validationOrder / return / customer; mappings finalized against your tenant's Interface Mapping Document.
IBM Sterling — OMS
In design-partner validationgetOrderList / returns via the REST API envelope; status codes configured to your pipeline.
Fixture-validated = mappings built and validated against the vendor's published API, live-certified at your first deployment. In design-partner validation = mappings finalized against your tenant's integration document during onboarding. Anything not listed here integrates directly via the API below.
Point-of-sale integration
The register turns a purchase into loyalty value in one call: post the sale as an order and SocialHub resolves the member (by your externalId, email, or memberId) and awards points by the program's own earn rules. Look up or create the member by your own key when you need to.
Award on a sale (post the order)
// One call: post the sale as an order. SocialHub resolves the member, applies the
// program's earn rules (tier multiplier + daily cap) and records the order — you
// don't compute points. The member is resolved by memberId > externalId > email.
POST https://flash.socialhub.ai/api/v2/orders
Authorization: Bearer fl_live_…
Idempotency-Key: pos-90871 // safe retries — one sale never awards twice
Content-Type: application/json
{
"externalOrderId": "90871",
"customer": { "externalId": "POS-CUST-5512" }, // or { "email": "…" } / { "memberId": "…" }
"totalAmount": 120.00,
"storeId": "st_…"
}
// → 200 { "data": { "awarded": 6, "balance": 1820, "memberId": "mem_…" } }
// Not a member yet → { "awarded": 0, "reason": "not-a-member" } (never auto-created).Find or create the member
// Look up a member by your own key or email (exact match), or create one:
GET https://flash.socialhub.ai/api/v2/members?externalId=POS-CUST-5512 // or ?email=ada@acme.com
// → 200 { "data": [ { "id": "mem_…", "externalId": "POS-CUST-5512", … } ], "total": 1 }
POST https://flash.socialhub.ai/api/v2/members // create/upsert (marketing consent stays OFF)
{ "email": "ada@acme.com", "fullName": "Ada Lovelace", "externalId": "POS-CUST-5512" }
// → 201 created / 200 existing (idempotent on externalId)Redeem a coupon at the register
// Cashier scans the member's coupon code → mark it redeemed at the register.
POST https://flash.socialhub.ai/api/v2/coupons/{couponId}/redeem
Authorization: Bearer fl_live_…
// → 200 redeemed
// → 404 coupon not found / already redeemed (treat as "do not honor")Read back a member's balance, tier and coupons with GET /members/{id}/points, /tier and /coupons to show them at the register.
Order-management integration
For e-commerce platforms with a native connector (Shopify, Amazon, TikTok Shop), turn it on and you are done. For any other order-management system, post your order events to the Orders API — ingest auto-awards by the program rules, and refunds claw points back proportionally. Your OMS drives the calls (no inbound webhook needed).
Orders earn; refunds claw back
// On Shopify / Amazon / TikTok Shop? Use the NATIVE channel connectors (Settings →
// Channels). For any OTHER OMS, your system calls these on its own order events.
//
// order paid / fulfilled → ingest (auto-awards by the program's earn rules):
POST https://flash.socialhub.ai/api/v2/orders
Idempotency-Key: SO-44821
{ "externalOrderId": "SO-44821", "customer": { "email": "ada@acme.com" }, "totalAmount": 240.00 }
// → 200 { "data": { "awarded": 12, "memberId": "mem_…" } }
// Same id + a DIFFERENT amount → 409 ORDER_CONFLICT (orders are immutable).
// order returned / refunded → proportional points claw-back, idempotent per refund:
POST https://flash.socialhub.ai/api/v2/orders/SO-44821/refund
{ "refundId": "re_1", "reason": "returned 1 item", "amount": 80.00 } // omit amount = full
// → 200 { "data": { "clawedBack": 4, "balance": 1816 } }
// Backfill / bulk: POST /orders/batch (≤100, 207 Multi-Status, per-item results).Not a member yet? Ingest returns awarded:0 / reason:not-a-member (never auto-creates). Enroll them with POST /members first when you want the order to earn.
ERP & master-data integration
Keep loyalty aligned with your system of record in both directions: push your store and member master (idempotent upsert by your externalId), then reconcile incrementally with ?updatedSince= so each sync only pulls what changed.
Push the store master
// Push your store master to SocialHub (upsert by your ERP store code):
POST https://flash.socialhub.ai/api/v2/stores
{ "name": "Downtown Flagship", "externalId": "ERP-STORE-018", "city": "New York" }
// → 201 created / 200 updated (idempotent on externalId)
// PUT /api/v2/stores/{id} updates a known store. GET to reconcile / pull ids.Push members & reconcile incrementally
// Push the member master (idempotent upsert by your externalId; consent OFF unless
// you explicitly opt in). Nightly full re-push is safe — existing members update.
POST https://flash.socialhub.ai/api/v2/members/batch // ≤100 per call, 207 Multi-Status
{ "members": [ { "email": "ada@acme.com", "fullName": "Ada Lovelace", "externalId": "ERP-7741" } ] }
// Incremental reconcile — only what changed since your last sync:
GET https://flash.socialhub.ai/api/v2/members?updatedSince=2026-06-26T00:00:00Z&limit=200
GET https://flash.socialhub.ai/api/v2/orders?updatedSince=2026-06-26T00:00:00Z // orders too
// For governed business metrics (GMV, redemption, active members) into BI, query the
// semantic layer over MCP (metrics:read) instead of aggregating raw rows yourself.Push the product catalog (PIM)
// Push your product catalog (idempotent upsert by your own external_id). One
// endpoint takes brands, categories, products, variants and inventory together.
POST https://flash.socialhub.ai/api/v2/catalog/import
{ "source": "erp",
"brands": [ { "externalId": "B-AURELIA", "name": "Aurelia" } ],
"categories": [ { "externalId": "C-RINGS", "name": "Rings" } ],
"products": [ { "externalId": "P-9001", "title": "Solitaire Ring",
"brandExternalId": "B-AURELIA", "categoryExternalId": "C-RINGS",
"descriptionHtml": "<p>18k…</p>",
"content": [ { "externalId": "P-9001-spec", "contentType": "spec",
"body": "1.0ct, 18k white gold, GIA" } ] } ],
"variants": [ { "externalId": "V-9001-7", "productExternalId": "P-9001",
"sku": "AUR-RING-7", "price": 4200 } ],
"inventory": [ { "variantSku": "AUR-RING-7", "locationRef": "WH-1", "available": 12 } ] }
// → 200 with per-entity {inserted,updated} + errors[] (a bad row never aborts the batch).
// On Shopify? Products map in automatically — images + rich descriptions included.
// Read back: GET /api/v2/products · /products/{id} · /categories · /brandsBatch ≤100/call (207 Multi-Status, per-item results); respect the per-key rate limit and run full re-syncs off-peak. The catalog import is external-mastered — SocialHub never writes products back to your ERP.
Auth, scopes & safety
Tenant-scoped keys
Every call carries a fl_live_ key bound to one team. Keys never cross tenants; create separate keys per integration so you can rotate one without touching the others.
Read vs write presets
Reconciliation jobs use a read-only key. Give a write scope only to the POS/OMS path that awards points or redeems coupons — least privilege per system.
Idempotency-Key
Send an Idempotency-Key header on writes (orders carry their own externalOrderId too). A retried call replays the original result; the same key with a different payload is rejected — one sale never awards twice.
Audited by default
Every API call is logged and visible under API Keys → recent activity, so an integration's writes are always traceable to a key.
Full endpoint reference: REST API · Quick Start · MCP (metrics into BI)
Integrating a backend system?
Talk to an engineer about your POS/OMS/ERP, member identity at the register, returns handling, or reconciliation jobs.
Talk to engineering