Home › Developers

Developers

Developer API and webhooks

Connect your own systems (a CRM, an ERP, your back office) to Vikalp Omni. Read your Omni Pass members, reviews, wishlists and referrals; add and take Omni Pass tokens; publish and hide reviews; and get a signed message the moment something changes. On the Pro and Max plans.

Keys

In Vikalp Omni, open Settings → Developers and create a key. Pick Read only, or Read and change for keys that add tokens or publish reviews. The key is shown once; keep it secret, like a password. Only the store owner and team admins can create keys.

Send the key with every call:

curl https://api.vikalpomni.com/api/v1/omni-pass/members/7012345678901 \
  -H "Authorization: Bearer vko_…"

Limits

ProMax
API calls a minute300600
API calls a month2,000,000Unlimited
Webhook addresses1025
Webhook messages a month1,000,000Unlimited

Every answer says how many calls are left this minute (X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset in seconds). Over the limit, the answer is 429: wait and try again. Monthly limits start again on the 1st (UTC).

Calls

All addresses start with https://api.vikalpomni.com/api/v1. Answers are JSON. Customer ids are Shopify’s (digits, as text); times are ISO 8601 in UTC; credits are in the smallest unit of your currency (cents, paise).

MethodAddressWhat it does
GET/shopYour store and its API limits
GET/omni-pass/tiersYour Omni Pass tiers
GET/omni-pass/membersMembers, a page at a time (filters: tier, updated_since)
GET/omni-pass/members/{customer_id}One member: tokens, credits, tier
GET/omni-pass/members/{customer_id}/activityEvery change to a member’s tokens and credits
POST/omni-pass/members/{customer_id}/tokensAdd tokens (positive amount) or take them (negative), with a reason
GET/reviewsReviews (filters: status, kind, product_id, customer_id, created_since)
GET/reviews/{id}One review
POST/reviews/{id}/publishShow a review on your store
POST/reviews/{id}/hideTake a review off your store
GET/wishlist/itemsSaved items (filters: customer_id, product_id, added_since)
GET/referralsReferrals (filters: status, referrer_customer_id, created_since)
GET/referrals/{id}One referral
GET/referrals/codes/{customer_id}A customer’s referral code and its clicks

Lists

Lists come a page at a time: ?page=1&limit=50 (up to 100). The answer is { "data": [...], "page": 1, "has_more": true }.

Adding and taking tokens

curl -X POST https://api.vikalpomni.com/api/v1/omni-pass/members/7012345678901/tokens \
  -H "Authorization: Bearer vko_…" -H "Content-Type: application/json" \
  -d '{"amount": 200, "reason": "Joined our events club", "idempotency_key": "club-7012345678901"}'

A negative amount takes tokens; a member can’t go below zero. Send an idempotency_key so a retried call changes nothing the second time. Customers who aren’t members yet join.

Errors

Errors are { "error": "…", "code": "…" } with the usual status: 400 something in the call is wrong, 401 no working key, 402 the plan doesn’t include the API, 403 a read-only key tried to change something, 404 not found, 409 not enough tokens, 429 over a limit.

Webhooks

In Settings → Developers, add an address (it must start with https://) and pick its events. We send each event as a POST with a JSON body:

{ "id": "…", "event": "omni_pass.balance_changed", "created_at": "2026-10-20T09:30:00.000Z",
  "shop": "yourstore.myshopify.com", "data": { … } }
EventWhen
omni_pass.balance_changedOmni Pass tokens or credits added or taken
omni_pass.tier_changedAn Omni Pass member moved to another tier
review.createdA new review arrived
referral.completedA referral was completed and rewarded

Answer with any 2xx status within 10 seconds. Otherwise we try again 10 times over about 3 hours. After 10 messages in a row aren’t delivered, the address is paused and Settings → Developers shows why; turn it on again once it’s fixed. The same event can arrive twice: use its id to skip repeats.

Checking the signature

Each message has X-Omni-Signature: t=<unix seconds>,v1=<signature>: an HMAC-SHA256 of <t>.<raw body> with the address’s signing secret (in Settings → Developers). Check it before trusting a message:

import { createHmac, timingSafeEqual } from 'node:crypto';

// header: the X-Omni-Signature header; body: the raw request body (a string)
function fromVikalpOmni(header, body, secret) {
  const parts = Object.fromEntries(header.split(',').map((p) => p.split('=')));
  const expected = createHmac('sha256', secret).update(`${parts.t}.${body}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
  return fresh && parts.v1?.length === expected.length && timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));
}

Questions

Email support@vikalpomni.com with “Developer API” in the subject.