Skip to main content
By the end of this guide your website lets a signed-in profile (the referrer) enter a friend’s name and email, and Omneo Invites emails the friend (the invitee) an invitation, tracks it, and records the referral when they join. Your site owns one step: collecting the referral and submitting it. Omneo owns the email, the join, and the incentive rules. This guide covers the developer’s part. For what the service does, read Omneo Invites. For who sets up what on the Omneo side, read Configuring Invites. Every endpoint is documented in the Invites API reference.

What you build and what Omneo provides

Invites has to be called as the referrer, with a token scoped to that one profile. You mint those tokens yourself. Everything else that authenticates you comes from Omneo. Health checks need no authentication: GET /invites/api/health returns 200, and GET /invites/api/version returns the service version.

Flow

The refer step

The token exchange needs your Omneo API token, so this chain runs on a server, never in the browser. Any backend you control works. On Shopify, a Shopify App Proxy is the natural home because Shopify tells you which customer is signed in. See Shopify authentication for how the Omneo Shopify extension handles the same problem.
1

Identify the referrer server-side

Establish which profile is signed in and what their ID is on your platform. Never trust a customer ID sent from the browser.On a Shopify App Proxy, verify the signature query parameter against your app’s shared secret before reading logged_in_customer_id, and reject the request if it is empty.
2

Exchange the customer ID for an Omneo ID token

Mint a profile-scoped token by external identity. With the Omneo SDK:
The same call as raw HTTP:
id is your platform’s customer ID as a string. Tokens are short-lived and exp is a Unix timestamp. Cache the token per referrer until shortly before it expires. Do not mint one per keystroke.A profile that was created on your platform seconds ago may not have synced to Omneo yet. In that window the create call in the next step returns 401. Treat a fresh token followed by 401 as “not synced yet” and show a try-again-shortly message instead of retrying in a loop.
3

Create the invite as the referrer

On 200 Omneo has already sent the email. You send nothing. The response does not echo recipient_first_name or public_message.
4

Handle the response

Log the returned invite id against your customer ID. Omneo support can look up any invite by ID when a referrer reports that a friend did not receive the email.

Showing invites remaining

  • meta.remaining is how many invites the referrer can still send. null means unlimited.
  • meta.eligible_definition.in_range is false when the campaign window is closed. Creating an invite will return 400.
  • “Friends who joined” are the entries in data with status equal to ACCEPTED.
  • data is ordered oldest first by invited_at.
The same token can also fetch one invite, resend it, or revoke it. None of these are needed for a basic integration. See Endpoints.

Lighter alternative: send referrers to Profile Portal

If you would rather not run a backend, link your “Refer a friend” button to https://[portal]/refer. The referrer signs in to Profile Portal and sends invites from there. Quota, email, and success messaging are built in. You lose the on-site experience but write no code. Link to /refer without query parameters.

The invitee’s journey

Omneo owns this part. It is described here so you can design around it.
  1. Omneo emails the invitee using your brand’s template. The call to action links to https://[portal]/join?invite_id={inviteId}&email={recipientEmail}. The join page pre-fills email, and also first_name, last_name, and mobile_phone if present in the query string.
  2. The invitee completes the join form. Profile Portal creates their profile and, server-side, tells Invites the invitation was accepted. Invites checks the email matches, writes the custom attribute invites.invited_by (the referrer’s profile ID) to the new profile, and marks the invite ACCEPTED.
  3. Other pending invites to that same address, from other referrers, are marked DECLINED. First accept wins.
  4. Your Reactions fire on the referral. See Referral incentives.
If the accept fails because the invite has expired, was already used, or the email was changed on the form, the invitee’s profile is still created. Only the referral credit is lost, and the invitee sees no error. If referral credit is business-critical, ask Omneo about monitoring pending invites whose invitee has since joined.

Accepting on your own site

If invitees create their account on your website rather than in Profile Portal, your backend performs the accept using a machine token Omneo issues for server-to-server calls.
Read invite_id from your sign-up page URL, keep it through the form, and call accept only after the customer account exists. recipient_email must equal the invited address exactly. recipient_external_id is the new customer’s ID on your platform. Invites finds or creates the Omneo profile by that ID first, then by email, so it converges with your platform-to-Omneo sync either way.
Decide this with Omneo before go-live. The identity handle that Invites links recipient_external_id under is a tenant-wide setting and cannot be changed once invites are in flight. It has one value when Profile Portal performs the accept and a different one when your website does. Mixing both accept paths in one tenant is not recommended.
State errors from validate and accept are listed in Error responses.

Things not to do

  • Do not call POST /api/v1/invites (without /me/). It exists for a legacy integration and does not send the email, enforce the referrer’s quota, or honour opt-outs. Use /api/v1/me/invites.
  • Do not put the Omneo API token, the machine token, or an ID token in browser JavaScript. All three stay on your server.
  • Do not add query parameters to /refer links. Link to the portal refer page as-is.

Security checklist

  • The Omneo API token and machine token live only in server configuration or a secret manager.
  • Every request to your handler is authenticated server-side before a customer ID is trusted. On Shopify, verify the App Proxy signature before reading logged_in_customer_id.
  • ID tokens are minted only for the profile proven to be signed in. Never accept a customer ID from the request body.
  • Nothing on your site links to /refer with query parameters.
  • Your own email and marketing tooling does not pre-fetch links in Omneo’s invitation emails. The opt-out link is a plain GET with no confirmation step.
  • The referral form is rate-limited per profile. The API’s 60 requests per minute is a backstop, not a UX limit.
  • Each returned invite id is logged with your customer ID so support can trace it.

Go-live checklist

Before you start, Omneo confirms: the Invites service is live for your tenant (GET /invites/api/health returns 200), your Omneo API token is issued, a test profile exists on your platform and in Omneo, and you have a staging host and a disposable inbox for the invitee.
  1. Sign in as the test profile on your website and submit the referral form with the disposable inbox address.
  2. Expect 200 and an invite id. GET /api/v1/me/invites shows it as PENDING with meta.remaining decremented, or null if unlimited.
  3. The disposable inbox receives the email. Its call to action links to https://[portal]/join?invite_id=...&email=....
  4. Complete the join form. GET /api/v1/me/invites as the referrer now shows the invite as ACCEPTED.
  5. Omneo confirms the new profile carries invites.invited_by equal to the referrer’s source_omneo_id, and that the referral Reaction fired.
  6. Negative checks: submit the same address again and expect a second PENDING invite, or your own de-duplication. Submit an address Omneo has blocked for the test and expect 403. Exhaust the quota on a definition with a small maximum and expect 400.