Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
API v1 has been updated with many new features, performance improvements, and a brand new roadmap that will empower our merchants to do so much more with our Public API.
Massive performance improvements: most if not all endpoints are operating anywhere between 1.5x and 8x faster than our previous implementation.
Stricter internal security.
Support for Tiers
A roadmap that will allow you to do many new and powerful things with our Public API.
Public API v1 will sunset in May of 2024!
API Keys are private and should not be shared or exposed on the front end.
As with v1, authentication is done via the request header. Include your API key as an X-Inveterate-Api-Key
header on all API endpoint requests.
All API requests utilize https://public.inveterateapi.com/v2.0/
as the base URL. If you have any issues, double check that you are prepending with https://
and appending /v2.0
.
curl -X GET "https://public.inveterateapi.com/v2.0/merchant"
-H "X-Inveterate-Api-Key: {api_key}"
As of now, admin and storefront methods operate in the same way--use the same API key in the header to authenticate both kinds of endpoints. The admin endpoints were created to model after admin actions within the merchant dashboard, while the storefront was made to model data that members are allowed to access.
In the (near) future, storefront endpoints will have their own "storefront" authentication through Shopify using a member's credentials. This will allow you to build authenticated apps and services outside of the Inveterate/Shopify ecosystem.
The storefront endpoints will always support authentication via the X-Inveterate-Api-Key
, however.
Create a credit redemption request for a member.
Triggered when a customer's payment is successfully processed.
customer.payment_succeeded
{
"payload": {
"customerId": "7733576892547",
"merchantId": "inveterate",
"createdAt": "2025-05-30T11:07:59.269Z",
"updatedAt": "2025-05-30T11:07:59.269Z",
"status": "PAID",
"detail": {
"amount": 100,
"currency": "USD",
"newBillingDate": "2025-07-30T00:00:00.000Z"
},
"customer": {
"id": "7733576892547",
"email": "[email protected]",
"phoneNumber": null
}
},
"metadata": {
"id": "4b3922a9-e878-3947-b283-57dfbd97d86c",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.payment_succeeded",
"version": "2025-06",
"triggerredAt": "2025-05-30T11:07:59.279Z"
}
}
payload
createdAt
(string): ISO timestamp when the event was created
updatedAt
(string): ISO timestamp when the event was last updated
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
status
(string): Payment status (e.g., "PAID")
detail
(object): Payment details
amount
(number): Payment amount
currency
(string): Currency code (e.g., "USD")
newBillingDate
(string): ISO timestamp for the next billing date
customer
(object): Customer information
id
(string): Customer identifier
email
(string): Customer's email address
phoneNumber
(string|null): Customer's phone number
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
Our storefront-authenticated endpoints.
Member accessing and altering endpoints.
Get your merchant data. Serves as a good health check for our services and your API key/access.
These endpoints only work for merchants with tiers enabled. Access benefits via this set of endpoints.
Get, create, update and delete webhook subscriptions. Use these to build third-party integrations.
Create a cancellation request for a member.
These endpoints only work for merchants with tiers enabled. Access benefits via this set of endpoints.
Get credits for a specific member.
This section contains information about how to customize your storefront UI.
Triggered when a customer's subscription is cancelled.
customer.cancelled
payload
createdAt
(string): ISO timestamp when the event was created
tierId
(string): Unique identifier for the tier the customer was cancelled from
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
updatedAt
(string): ISO timestamp when the event was last updated
detail
(object): Additional details about the cancellation
cancellationSource
(string): Reason for cancellation (e.g., "FAILURE", "CUSTOMER", "MERCHANT")
tierName
(string): Name of the tier that was cancelled
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
The Rest API allows you to build a highly custom paid-membership program on your Shopify storefront.
Find the v2 reference .
API Keys are private and should not be shared or exposed on the front end.
Include your API key as an X-Inveterate-Api-Key
header on all API endpoint requests.
All API requests utilize https://public.inveterateapi.com/
as the base URL.
Member get. Includes more member actions in sub-directories.
Campaigns are directly associated with the Early Access benefit. It represents what collections will utilize the early access benefit and between what timeframes.
A campaign
is represented as an object with the following structure:
GET
https://public.inveterateapi.com/campaigns
{
"payload": {
"createdAt": "2025-05-30T10:40:47.081Z",
"tierId": "3a636361",
"merchantId": "inveterate",
"detail": {
"cancellationSource": "FAILURE",
"tierName": "PAID"
},
"updatedAt": "2025-05-30T10:40:47.081Z",
"customerId": "7733540520067"
},
"metadata": {
"id": "e3d8d8cc05d1ac397cb5d89e417d2350",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.cancelled",
"version": "2025-06",
"triggerredAt": "2025-05-30T10:40:47.613Z"
}
}
Once the webhook subscription is in place, you can have it choose to act on or disregard each of the types of events.
Customer events
Cancellations
Triggered when a customer joins a free trial tier in the loyalty program.
customer.joined.free_trial
{
"payload": {
"createdAt": "2025-05-30T13:51:00.551Z",
"tierId": "c669d6e7",
"merchantId": "inveterate",
"detail": {
"entryType": "SUBSCRIPTION_PURCHASE",
"tierName": "TrialTier"
},
"updatedAt": "2025-05-30T13:51:00.551Z",
"freeTrialStart": "2025-05-30T13:50:47.177Z",
"freeTrialEnd": "2025-06-04T13:50:47.175Z",
"customerId": "8921477710119"
},
"metadata": {
"id": "2297571615b78a717726569a0bfed6fa",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.joined.free_trial",
"version": "2025-06",
"triggerredAt": "2025-05-30T13:51:01.817Z"
}
}
payload
createdAt
(string): ISO timestamp when the event was created
tierId
(string): Unique identifier for the trial tier the customer joined
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
updatedAt
(string): ISO timestamp when the event was last updated
freeTrialStart
(string): ISO timestamp when the free trial started
freeTrialEnd
(string): ISO timestamp when the free trial ends
detail
(object): Additional details about the trial entry
entryType
(string): How the customer joined (e.g., "SUBSCRIPTION_PURCHASE")
tierName
(string): Name of the trial tier
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
Triggered when a customer changes from one tier to another in the loyalty program.
customer.changed_tier
{
"payload": {
"createdAt": "2025-05-30T11:17:19.646Z",
"tierId": "6a538edc",
"merchantId": "inveterate",
"detail": {
"previousTierName": "PAID0402",
"previousTierId": "3a636361",
"tierName": "FREE"
},
"updatedAt": "2025-05-30T11:17:19.646Z",
"customerId": "7733576892547"
},
"metadata": {
"id": "3b8313888e852a1b4a285dbe4334a610",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.changed_tier",
"version": "2025-06",
"triggerredAt": "2025-05-30T11:17:21.144Z"
}
}
payload
createdAt
(string): ISO timestamp when the event was created
tierId
(string): Unique identifier for the new tier the customer moved to
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
updatedAt
(string): ISO timestamp when the event was last updated
detail
(object): Additional details about the tier change
previousTierName
(string): Name of the tier the customer moved from
previousTierId
(string): ID of the tier the customer moved from
tierName
(string): Name of the new tier the customer moved to
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
Triggered when a customer's payment method is updated.
customer.payment_methods.updated
{
"payload": {
"customerId": "23076025210636",
"merchantId": "inveterate",
"createdAt": "2025-06-16T01:13:06.342Z",
"updatedAt": "2025-06-16T01:13:06.342Z",
"customer": {
"id": "23076025210636",
"email": "[email protected]"
},
"detail": {
"paymentMethodId": "gid://shopify/CustomerPaymentMethod/47d624851460af123479714ff98ff616",
"paymentMethodType": "CustomerCreditCard"
}
},
"metadata": {
"id": "213c98aa-f4bd-90b4-aebe-9b1501fdd0c3",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.payment_methods.updated",
"version": "2025-06",
"triggerredAt": "2025-06-16T01:13:06.358Z"
}
}
payload
customerId
(string): Customer identifier
merchantId
(string): Merchant identifier
createdAt
(string): ISO timestamp when the event was created
updatedAt
(string): ISO timestamp when the event was last updated
customer
(object): Customer information
id
(string): Customer identifier
email
(string): Customer's email address
detail
(object): Payment method details
paymentMethodId
(string): Unique identifier for the payment method
paymentMethodType
(string): Type of payment method (e.g., "CustomerCreditCard")
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
When a member is created in our system we add a few values to Shopify customer metafields to make it easier to utilize specific information on the storefront website.
This field is the store credits balance of the customer. This number indicates the amount of store credits they have received, but have not yet redeemed.
This filed displays the next payment date for the customer's membership. It is stored in ISO format.
This field displays a list of all completed referrals made by the member.
This field displays the amount the member has agreed to paying for the membership.
{
collectionIds: Array[String],
endDate: String,
updatedAt: String,
startDate: String,
createdAt: String,
id: String,
name: String,
merchantId: String
}
This set of benefit endpoints should only be used by merchant that have Tiers disabled. Benefit access for merchants that have enabled Tiers can be found in the Tiers tab in this API reference.
Triggered when a billing attempt fails but there may be more retry attempts remaining.
customer_billing.attempt.failed
payload
createdAt
(string): ISO timestamp when the event was created
updatedAt
(string): ISO timestamp when the event was last updated
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
customer
(object): Customer information
id
(string): Customer identifier
email
(string): Customer's email address
phoneNumber
(string|null): Customer's phone number
detail
(object): Billing attempt details
amount
(number): Amount that failed to be charged
currency
(string): Currency code (e.g., "USD")
errorMessage
(string): Description of the billing failure
billingDate
(string): ISO timestamp of billing date
attemptedAt
(string): ISO timestamp of billing attempted date
lastAttemptAt
(string): ISO timestamp of last billing attempted date
billingAttempts
(number): Number of billing attempts made so far
billingTierId
(string): ID of the billing tier being charged
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
Triggered when a customer's payment has failed after all retry attempts have been exhausted.
customer.payment_failed
payload
createdAt
(string): ISO timestamp when the event was created
updatedAt
(string): ISO timestamp when the event was last updated
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
customer
(object): Customer information
id
(string): Customer identifier
email
(string): Customer's email address
phoneNumber
(string|null): Customer's phone number
detail
(object): Payment failure details
amount
(number): Amount that failed to be charged
currency
(string): Currency code (e.g., "USD")
errorMessage
(string): Description of the payment failure
billingDate
(string): ISO timestamp of when billing was attempted
billingAttempts
(number): Total number of billing attempts made
billingTierId
(string): ID of the billing tier being charged
isFinal
(boolean): Whether this is the final attempt (always true for this event)
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
Triggered when a customer's credit balance is updated (credits earned or redeemed).
customer.credits.updated
payload
createdAt
(string): ISO timestamp when the event was created
updatedAt
(string): ISO timestamp when the event was last updated
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
email
(string): Customer's email address
firstName
(string): Customer's first name
lastName
(string): Customer's last name
amount
(number): Amount of credits involved in this transaction
newBalance
(number): Customer's new credit balance after this transaction
previousBalance
(number): Customer's credit balance before this transaction
reason
(string): Reason for the credit update (e.g., "EARNED_FROM_PURCHASE")
orderId
(string): ID of the order associated with this credit transaction (if applicable)
orderTotal
(number): Total value of the associated order (if applicable)
expirationDate
(string): ISO timestamp when these credits will expire
note
(string|null): Additional notes about the credit transaction
appliedBy
(string|null): Who applied the credits (if manually applied)
isUpsell
(boolean): Whether this credit transaction was part of an upsell
metadata
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
Triggered when a customer has requested cancellation but the cancellation is scheduled for a future date.
customer.pending_cancellation
payload
createdAt
(string): ISO timestamp when the event was created
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
updatedAt
(string): ISO timestamp when the event was last updated
detail
(object): Additional details about the pending cancellation
nextSegmentId
(string|null): ID of the next segment (if applicable)
cancellationSource
(string): Who initiated the cancellation (e.g., "CUSTOMER")
switchToFreeTier
(boolean|null): Whether switching to free tier instead of complete cancellation
effectiveCancellationDate
(string): ISO timestamp when the cancellation will take effect
cancelRequest
(object): Detailed information about the cancellation request
createdAt
(string): When the cancellation request was created
cancelDate
(string): When the cancellation will be effective
nextSegmentId
(string|null): Next segment ID
cancellationSource
(string): Source of cancellation
merchantId
(string): Merchant identifier
billingTierId
(string): ID of the billing tier being cancelled
switchToFreeTier
(boolean): Whether to switch to free tier
contractId
(string): Contract ID being cancelled
customerId
(string): Customer identifier
cancelToken
(string): Unique cancellation token
updatedAt
(string): When the request was last updated
status
(string): Current status (e.g., "PENDING_CANCELLATION")
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
This is an advanced guide.
Since we accommodate a wide variety of merchants who utilize a wide variety of themes, our code does not directly make changes to general functionality of themes. For instance, some themes will automatically update the cart contents and the cart icon in real-time when a product is added to cart and some do not. At a base level, our add to cart button on the landing page will do the following:
Add the membership to cart (if it's not already in cart)
Update add to cart buttons on the page with a success state
Refresh the page with ?cart-updated=true
added to the URL
Once the page reloads, it uses the URL param from step #3 to display a success message to the customer
Again, we have this functionality in place to make sure we can provide a great user experience for all merchant's customers.
In instances where the theme has slide out cart behavior and our above solution is interfering with that behavior, we provide the option to disable the steps #3 and #4 from above so that you can continue to maintain the user experience that's unique to your brand.
There are 2 ways to do this:
Add the following HTML script tag within the head of your theme.liquid file and this will disable steps #3 and #4 behavior on the landing page:
Our landing page will automatically pick up that object and disable the functionality.
We've also added a utility function that's only on the landing page to allow you to update the addToCartRedirect
setting after our code has already loaded on the page. To use this method, you'll want to first make sure that window.inveterate.landing.updateLPSettings
exists by using something like a setInterval
or a while
loop and then from there you can use that to update settings:
This will run 100 times and will run every 500ms. Once it either finds window.inveterate.landing.updateLPSettings
or if the counter reaches 100, it will end the loop. The reason for the counter is to prevent this from running forever and having an impact on performance. If it doesn't find it after 100, it probably isn't loading on the page.
On your storefront, we automatically add and update 2 files:
inveterate-theme.liquid
inveterate-checkout.liquid
See for more information about this.
The Inveterate Storefront code is code used to implement front end solutions involving memberships. It contains useful data and helpful functions we use for our standard features, as well as merchant to merchant custom features.
inveterate
objectAll of the storefront code is contained within a single object called inveterate
, which is attached to the window
object.
To explore everything contained in the inveterate
object, type the following code in your browser console:
Visit the following links for more information about what's contained within the inveterate
object.
{
"payload": {
"customerId": "7733540520067",
"merchantId": "inveterate",
"createdAt": "2025-05-30T10:40:38.660Z",
"updatedAt": "2025-05-30T10:40:38.660Z",
"customer": {
"id": "7733540520067",
"email": "[email protected]",
"phoneNumber": null
},
"detail": {
"amount": 100,
"currency": "USD",
"errorMessage": "Payment method was revoked",
"billingDate": "2025-06-30T07:00:00.000Z",
"attemptedAt": "2025-06-30T07:00:00.000Z",
"lastAttemptedAt": "2025-06-30T07:00:00.000Z",
"billingAttempts": 3,
"billingTierId": "3a636361"
}
},
"metadata": {
"id": "f8e4a11b-d12f-18f4-98e5-49bb16c7bc4e",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer_billing.attempt.failed",
"version": "2025-06",
"triggerredAt": "2025-05-30T10:40:38.682Z"
}
}
{
"payload": {
"customerId": "7733560541315",
"merchantId": "inveterate",
"createdAt": "2025-05-30T11:01:00.674Z",
"updatedAt": "2025-05-30T11:01:00.674Z",
"customer": {
"id": "7733560541315",
"email": "[email protected]",
"phoneNumber": null
},
"detail": {
"amount": 100,
"currency": "USD",
"errorMessage": "Payment method was revoked",
"billingDate": "2025-06-30T07:00:00.000Z",
"billingAttempts": 3,
"billingTierId": "3a636361",
"isFinal": true
}
},
"metadata": {
"id": "1c77f905-8a5c-eaf7-ab62-1db3405eec81",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.payment_failed",
"version": "2025-06",
"triggerredAt": "2025-05-30T11:01:00.713Z"
}
}
{
"payload": {
"lastName": "1",
"note": null,
"reason": "EARNED_FROM_PURCHASE",
"amount": 1,
"isUpsell": false,
"orderId": "6244265853059",
"newBalance": 1,
"orderTotal": 100,
"previousBalance": 0,
"createdAt": "2025-05-30T10:18:11.721Z",
"firstName": "1a",
"merchantId": "inveterate",
"customerId": "7733540520067",
"appliedBy": null,
"expirationDate": "2025-05-31T10:00:00.000Z",
"updatedAt": "2025-05-30T10:18:11.721Z",
"email": "[email protected]"
},
"metadata": {
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.credits.updated",
"version": "2025-06",
"triggerredAt": "2025-05-30T10:18:12.985Z"
}
}
{
"payload": {
"createdAt": "2025-05-30T11:20:43.043Z",
"merchantId": "inveterate",
"detail": {
"nextSegmentId": null,
"cancellationSource": "CUSTOMER",
"switchToFreeTier": null,
"cancelRequest": {
"createdAt": "2025-05-30T11:20:36.919Z",
"cancelDate": "2025-06-30T11:00:00Z",
"nextSegmentId": null,
"cancellationSource": "CUSTOMER",
"merchantId": "inveterate",
"billingTierId": "6a538edc",
"switchToFreeTier": false,
"contractId": "23578214531",
"customerId": "7733576892547",
"cancelToken": "15ae1f74-9555-456a-b003-da5ec076a48e",
"updatedAt": "2025-05-30T11:20:40.234Z",
"status": "PENDING_CANCELLATION"
},
"effectiveCancellationDate": "2025-06-30T11:00:00Z"
},
"updatedAt": "2025-05-30T11:20:43.043Z",
"customerId": "7733576892547"
},
"metadata": {
"id": "de453003ee3da27b9ac7543cb49f5e77",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.pending_cancellation",
"version": "2025-06",
"triggerredAt": "2025-05-30T11:20:44.093Z"
}
}
<script>
window.inveterateLPSettings = { addToCartRedirect: false };
</script>
let inveterateCounter = 0;
const inveterateInterval = setInterval(() => {
if (window.inveterate && window.inveterate.landing && window.inveterate.landing.updateLPSettings) {
window.inveterate.landing.updateLPSettings({ addToCartRedirect: false });
clearInterval(inveterateInterval);
return;
}
inveterateCounter += 1;
if (inveterateCounter >= 100) {
clearInterval(inveterateInterval);
}
}, 500);
Triggered when a customer places an order.
customer.ordered
{
"payload": {
"merchantId": "inveterate",
"createdAt": "2025-06-04T10:30:49.653Z",
"updatedAt": "2025-06-04T10:30:49.653Z",
"customer": {
"id": 7741425221763,
"email": "[email protected]"
},
"detail": {
"subtotal_price": "629.95",
"currency": "USD",
"line_items": [
{
"id": 14497615544451,
"name": "The Multi-managed Snowboard",
"price": "629.95",
"quantity": 1,
"variant_id": 44858553761923,
"product_id": 8469201158275
}
]
}
},
"metadata": {
"id": "228491c3-a7db-6b83-5d11-4fcecda101d3",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.ordered",
"version": "2025-06",
"triggerredAt": "2025-06-04T10:30:49.934Z"
}
}
payload
createdAt
(string): ISO timestamp when the event was created
updatedAt
(string): ISO timestamp when the event was last updated
merchantId
(string): Merchant identifier
customer
(object): Customer information
id
(number): Customer identifier
email
(string): Customer's email address
detail
(object): Order details
subtotal_price
(string): Subtotal amount of the order
currency
(string): Currency code (e.g., "USD")
line_items
(array): Array of ordered items
id
(number): Line item identifier
name
(string): Product name
price
(string): Item price
quantity
(number): Quantity ordered
variant_id
(number): Product variant identifier
product_id
(number): Product identifier
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
All Inveterate properties can be found in the properties
namespace within the inveterate
object.
To view the properties
object paste the following into the browser console:
window.inveterate.properties
The above code will display the following object structure:
{
benefits: Object,
campaigns: Array[Object],
constants: Object,
customer: Object,
pageType: String,
product: Object,
redirectUrl: String,
referralApiUrl: String,
referralData: Object,
referralStorageName: String
}
benefits
: An object of benefits you have enabled/disabled and all of the settings associated with them.
campaigns
- An object of campaigns you have created in association with the Early Access benefit.
constants
- Object is empty at the moment.
customer
- An object containing information about the current signed in customer and their membership status.
pageType
: The type of page you're currently on.
product
: An object containing details about the membership subscription product.
redirectUrl
: The default URL location of the landing page.
referralApiUrl
: URL for making get request to track referrals.
referralData
: An object containing the details of a referral in progress.
referralStorageName
: The name where referral data is stored within localStorage.
window.inveterate
{
"success": true,
"data": {
"campaigns": [
{
"collectionIds": [
"gid://shopify/Collection/1234567890"
],
"endDate": "2022-05-24 20:26:03 +00:00",
"updatedAt": "2022-05-13T20:26:13.267Z",
"startDate": "2022-05-13 20:26:01 +00:00",
"createdAt": "2022-05-13T20:26:13.267Z",
"id": "c7fd8ce6-f54e-4b1d-9841-1593f4c9bc70",
"name": "Inveterate Campaign",
"merchantId": "inveterate"
}
],
"count": 1
},
"errors": []
}
curl -X GET "https://public.inveterateapi.com/merchant"
-H "X-Inveterate-Api-Key: {api_key}"
const merchant = await fetch('https://public.inveterateapi.com/merchant', {
headers: {
'Content-Type': 'application/json',
'X-Inveterate-Api-Key': '{api_key}',
},
method: 'GET',
}).then(data => data.json());
Triggered when a customer's information is updated.
customer.updated
{
"payload": {
"newData": {
"accountState": "ENABLED",
"lastCreditRedemptionAt": null,
"lastName": "inveterate",
"notes": null,
"anonymized": false,
"createdAt": "2025-05-25T00:27:56.503Z",
"revenue": 102.32,
"merchantId": "inveterate",
"paymentId": null,
"referrals": 0,
"customerId": "22978031812972",
"credit": 10,
"email": "[email protected]",
"updatedAt": "2025-05-25T00:27:59.220Z",
"joinedAt": "2025-05-25T00:27:52Z",
"trigger": "PAID_SUBSCRIPTION",
"firstName": "inveterate",
"creditsEarned": 10,
"phoneNumber": "+16416805498",
"referredBy": null,
"contractId": 82559795564,
"lastPurchaseAt": "2025-06-12T12:40:44.819Z",
"currencyCode": "USD",
"freeTrialActive": false,
"status": "ACTIVE",
"tierId": "c560bce7",
"tierName": "PAID"
},
"oldData": {
"accountState": "ENABLED",
"lastCreditRedemptionAt": null,
"lastName": "inveterate",
"notes": null,
"anonymized": false,
"spendingProcess": {
"time": "2025-06-12T12:40:44.819Z",
"status": "ACTIVE"
},
"createdAt": "2025-05-25T00:27:56.503Z",
"revenue": 102.32,
"merchantId": "inveterate",
"paymentId": null,
"referrals": 0,
"customerId": "22978031812972",
"credit": 10,
"email": "[email protected]",
"updatedAt": "2025-05-25T00:27:59.220Z",
"joinedAt": "2025-05-25T00:27:52Z",
"trigger": "PAID_SUBSCRIPTION",
"firstName": "inveterate",
"creditsEarned": 10,
"phoneNumber": "+16416805498",
"referredBy": null,
"contractId": 82559795564,
"lastPurchaseAt": "2025-06-12T12:40:44.819Z",
"currencyCode": "USD",
"freeTrialActive": false,
"status": "ACTIVE",
"tierId": "c560bce7",
"tierName": "PAID"
}
},
"metadata": {
"id": "056f9ad3c189f9897e893c8477fce1f6",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.updated",
"version": "2025-06",
"triggerredAt": "2025-06-12T12:40:46.309Z"
}
}
payload
newData
(object): Updated customer data
accountState
(string): Current state of the account (e.g., "ENABLED")
lastCreditRedemptionAt
(string|null): ISO timestamp of last credit redemption
lastName
(string): Customer's last name
notes
(string|null): Additional notes about the customer
anonymized
(boolean): Whether the customer data is anonymized
createdAt
(string): ISO timestamp when the customer was created
revenue
(number): Total revenue from the customer
merchantId
(string): Merchant identifier
paymentId
(string|null): Payment identifier
referrals
(number): Number of referrals made by the customer
customerId
(string): Customer identifier
credit
(number): Available credit amount
email
(string): Customer's email address
updatedAt
(string): ISO timestamp when the customer was last updated
joinedAt
(string): ISO timestamp when the customer joined
trigger
(string): Trigger type (e.g., "PAID_SUBSCRIPTION")
firstName
(string): Customer's first name
creditsEarned
(number): Total credits earned by the customer
phoneNumber
(string): Customer's phone number
referredBy
(string|null): Identifier of the customer who referred this customer
contractId
(number): Contract identifier
lastPurchaseAt
(string): ISO timestamp of last purchase
currencyCode
(string): Currency code (e.g., "USD")
freeTrialActive
(boolean): Whether the customer has an active free trial
status
(string): Customer status (e.g., "ACTIVE")
tierId
(string): Membership tier identifier
tierName
(string): Name of the membership tier
oldData
(object): Previous customer data before the update
Contains the same fields as newData
May include additional fields like spendingProcess
that were removed in the update
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
Our admin endpoints.
Get and create credit requests.
This page covers api endpoints that allow merchants add customers to their free tier membership
To sign up for free tier membership, customer has to be registered in Shopify.
{
merchantId: string,
customerId: string,
segmentId: string?,
}
POST
https://public.inveterateapi.com/signup-free-tier
merchantId*
String
merchantId is the first part of the shop domain. For example if the shop domain is inveterate-demo.myshopify.com, Merchant ID is inveterate-demo
customerId*
String
Shopify legacy customer IDs with numerical values such as "6412233234" are supported. GraphQL IDs such as "gid://shopify/Customer/6412233234" are not supported
segmentId
String
Optionally provided to specify which free tier the customer is to be enrolled into. If absent, the first free tier to be created is assumed.
This is an advanced guide.
Inveterate utilizes Shopify's native subscription functionality to provide a seamless purchasing experience for your customers. We create a normal product in your Shopify instance, but the main differences between this product and other products is it has a selling plan attached to it and it's a subscription-only product. A selling plan is the mechanism Shopify uses to identify how a subscription product should be billed and shipped to the customer. These selling plans have an ID attached to them which is required when adding the product to cart for Shopify to understand it needs to be treated line a subscription.
Normally, when adding a product to cart through Shopify's AJAX Cart API, you would do the following:
fetch('/cart/add.js', {
body: JSON.stringify({items: [
{
id: 42892755009790,
quantity: 1,
},
]}),
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
}).then(res => res.json()).then(items => console.log(items));
As shown above, we are adding one item to cart by passing in its variant ID and quantity in the id
and quantity
fields. For subscription products we would add the following change:
fetch('/cart/add.js', {
body: JSON.stringify({items: [
{
id: 42869694497022,
quantity: 1,
selling_plan: 3055124734,
properties: {
_inveterate_subscription: true
},
},
]}),
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
}).then(res => res.json()).then(items => console.log(items));
As shown above, we have mostly the same code with one small tweak. In the items
array we've updated the item we're adding to have the selling plan id (seen in the selling_plan
field). As mentioned earlier, this is what lets Shopify know that this is a subscription product and should be treated as such during checkout as well as in Shopify's backend system.
Shopify does not display the selling plan ID in their admin, which makes it a little tougher to find. In our front end JavaScript, we've added some properties to help.
On the front end storefront of your site (any page besides checkout) type inveterate
into your browser console. This should return an Object that looks something like this (if yours looks slightly different you're using a newer version):
If you see an error, that usually means the Inveterate app embed has not been enabled in the theme settings yet. Once enabled, you should be able to see this.
Next, type inveterate.properties.product
. You should see the following:
If you see an error or "falsey" value, that usually means the product either has not been created correctly, is still in "Draft" mode in Shopify or is not in the "Online Store" sales channel. Check those three options before continuing.
With those 2 checks out of the way, you should be able to type in: inveterate.properties.product.selling_plan_groups[0].selling_plans[0].id
which should display something like:
Those numbers are you selling plan ID. This is what you pass along to Shopify when adding the product to cart.
See Shopify's Documentation as well for more information on selling plans.
One last thing to notice in the fetch
code snippet above is that we're passing in a properties
object to Shopify with _inveterate_subscription: true
. This is a useful troubleshooting tool to identify how the membership product was added to cart. This is not required, but strongly recommended to add.
When setting up a landing page with multiple tiers, the process remains the same for each ATC button. As you configure each one, you just need to ensure you select the correct product and selling plan for each ATC button.
You can find the product, variant and selling plan information for each tier in our inveterate.membershipProducts
property.
If you use a custom Landing Page, you will need to adjust the Add To Cart code further in order for the benefit to work properly. In the guide above, only one product was added to the [items] array. In order to configure the Free Gift benefit, all you need to do is add the second (free gift) product to the array as well.
This is an example of one product:
body: JSON.stringify({items: [
{
id: 42869694497022,
quantity: 1,
selling_plan: 3055124734,
properties: {
_inveterate_subscription: true
},
},
]}),
This is an example of two products, e.g. the membership product and the free gift:
body: JSON.stringify({items: [
{
id: 42869694497022,
quantity: 1,
selling_plan: 3055124734,
properties: {
_inveterate_subscription: true
},
},
{
id: 1234567890,
quantity: 1,
properties: {
_inveterate_free_signup_gift: true
}
}
]}),
This set of benefit endpoints should only be used by merchant that have Tiers disabled. Benefit access for merchants that have enabled Tiers can be found in the Tiers tab in this API reference.
This page covers API endpoints that allow merchants to retrieve and modify user credits.
Internally, credits are stored with a long list of attached data-values used for internal operations. For the purposes of this documentation, credit
entries are represented with the following structure:
{
amount: number;
createdAt: string;
newBalance: number;
reason: string;
}
GET
https://public.inveterateapi.com/customers/credits
This endpoint will pull all credit history for a given user. For batch operations, each customerId
should be its own API call. Ensure that query parameter customerId
is included after the endpoint path, in the form of:
.../customers/credits?customerId=1234567890
customerId*
Number
The customer ID which you intend to pull the data of.
X-Inveterate-Api-Key*
String
Required to access all protected endpoints on this API. Obtained from merchant's Inveterate dashboard.
In the case of a success, you will see a return that looks like the following:
{
"credits": [
{
"amount": 5,
"createdAt": "2000-01-01T12:00:00.000Z",
"newBalance": 10,
"reason": "MANUAL"
},
{
... // another object of the same structure
}
... // more objects of the same structure
],
/*
* If the user has activated a discount code for redemption
* through their member portal, it will be included here as follows.
*
* If there is no active code, redemption will be null.
*/
"redemption": {
"code": "REDEEM+123456789", // always begins with "REDEEM+"
"value": 5 // USD
}
}
NOTE: Please keep in mind that the response is exactly as it appears in the credit ledger. This means that all credits, even expired credits, will appear in the response. If you are using the Expiring Credits benefit and you want to calculate an accurate balance for a customer, ensure that you check the returned entries for expired entries and deduct those values.
In the case of a missing customerId
parameter, you will receive the following:
{
"success": false,
"data": {},
"errors": [
"Missing query parameter: customerId"
]
}
In the case of a missing or invalid X-Inveterate-Api-Key
, you will receive the following:
{
"message": "Unauthorized"
}
POST
https://public.inveterateapi.com/customers/credits
This endpoint will create a ledger entry for a given customerId
, enabling you to add credits to a customer. For batch operations, each customerId
should be its own API call. Ensure that the query parameters, customerId
and credit
, are included in the path in the form:
.../customers/credits?customerId=1234567890&credit=5
customerId*
Number
The ID which identifies the customer you intend to add credits to.
credit*
Number
The credit amount you intend to add to the customer.
X-Inveterate-Api-Key
String
Required to access all protected endpoints on this API. Obtained from merchant's Inveterate dashboard.
Please note that 200 does not guarantee that the request was actually successful. It means that our back-end successfully received the request and it is being processed. The only place where this could serve to be an issue is the case that you enter an incorrect customerId
.
If you are manually inputting all customerId
values for batch calls, you can ensure that the call was successful by performing a GET
call and confirming the createdAt
date. Please keep in mind that there may be a few-second delay before the credits are fully processed and added in our back-end.
You will receive a number of different errors, similar to the ones in the GET
endpoint (please review those two errors for reference), if you don't include the two query parameters or if your X-Inveterate-Api-Key
is invalid.
POST
https://public.inveterateapi.com/redemption-discount-code
Create a request to redeem credits as a discount code that can be used by a customer. All data should be passed through the request body (see parameters).
customerId*
number
The customer ID for which you intend to create a redemption request for.
amount*
number
The amount of credits you would like to redeem to this discount code.
string
The email for the customer. This may not be required. If a request fails, attempt the request with the customers email.
merchantId*
string
The merchant ID for the store.
On failure, you will receive a code 400. There are a few reasons this may be. Primarily, an incomplete body in the request.
On success, you will receive a response code 200 and the response body will contain the discount code generated by our back-end.
Referencing an inexistent customerId
or the referenced customer having insufficient funds are the two main reasons for failures.
Triggered when a customer's credits have expired and are removed from their balance.
customer.credits.expired
{
"payload": {
"merchantId": "inveterate",
"customerId": "7733592490115",
"newBalance": 0,
"previousBalance": 5,
"reason": "EXPIRED",
"expiredAt": "2025-05-30T11:29:07.875Z",
"email": "[email protected]",
"firstName": "1",
"lastName": "1",
"amount": 5
},
"metadata": {
"id": "e62649ec-851a-6f7a-1f78-fe9e66f8a81b",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.credits.expired",
"version": "2025-06",
"triggerredAt": "2025-05-30T11:29:08.049Z"
}
}
payload
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
email
(string): Customer's email address
firstName
(string): Customer's first name
lastName
(string): Customer's last name
amount
(number): Amount of credits that expired
newBalance
(number): Customer's new credit balance after expiration
previousBalance
(number): Customer's credit balance before expiration
reason
(string): Reason for the credit change (always "EXPIRED" for this event)
expiredAt
(string): ISO timestamp when the credits expired
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
A merchant
is represented as an object with the following structure:
{
currency: String,
customerCount: Number,
country: String,
createdAt: String,
creditsEnabled: Boolean,
currency: String,
email: String,
firstName: String,
landingPageEnabled: Boolean,
lastName: String,
merchantId: String,
merchantName: String,
myshopifyDomain: String,
phone: String,
savedSearchId: String,
status: String,
subscriptionProduct: String,
updatedAt: String
}
GET
https://public.inveterateapi.com/merchant
Gets merchant data.
X-Inveterate-Api-Key*
String
Required to access all protected endpoints on this API. Obtained from merchant's Inveterate dashboard.
{
"data": {
"merchant": {
"currency": "USD",
"customerCount": 2374,
"country": "United States",
"createdAt": "2022-01-01T12:00:00.000Z",
"creditsEnabled": true,
"currency": "USD",
"email": "[email protected]",
"firstName": "Inveterate",
"landingPageEnabled": true,
"lastName": "Example",
"merchantId": "inveterate",
"merchantName": "Inveterate",
"myshopifyDomain": "inveterate.myshopify.com",
"phone": "555-123-4567",
"savedSearchId": "gid://shopify/Segment/1234567890",
"status": "ACTIVE",
"subscriptionProduct": "gid://shopify/Product/1234567890",
"updatedAt": "2022-01-01T12:00:00.000Z"
}
}
"success": true,
"errors": []
}
{
"data": {}
"success": false,
"errors": [
"Invalid API key"
]
}
Use the "Create Webhook Subscriber" endpoint and pass in a callbackUrl
on your system that will receive a POST request for all of events listed below.
Once the webhook subscriber is in place, you can have it choose to act on or disregard each of the following types of events.
Merchant events
merchant.updated
merchant.reinstall
Customer events
Account
customer.created
customer.updated
customer.credits.updated
Orders and Payments
customer.ordered
customer.resubscribed
customer.payment_succeeded
customer.payment_failed
customer.payment_methods.updated
customer_billing.attempt.failed
Cancellations –
customer.cancellation_requested
customer.confirmed_cancellation
customer.cancelled
customer.merchant_cancel
The token
field in the response body for the Create Webhook Subscriber endpoint is important to take note of. For security reasons, it only appears here, and in the body of post requests for events forwarded from the Inveterate system to the subscriber's callbackUrl
. This will allow your 3rd party app to make sure the requests made to your endpoint are legitimate. Simply store the token
value you get when you create the subscriber, and check for incoming events on your callbackUrl
for a matching token in the request body.
POST
https://public.inveterateapi.com/webhooks
You may have wondered about the createdByApp
field in the response body for the "Create Webhook Subscriber" request. This is derived from the app
field which is attached behind the scenes to your API key (the X-Inveterate-Api-Key
one). For example, let's say you work at a SaaS company called "Smithy", and are developing an integration with Inveterate. Then the API key you are issued to access the Inveterate API will have an app
field value of Smithy
, and all the webhook subscriber objects created with your API key will have the same createdByApp
value.
TLDR: The "Get Webhook Subscribers" endpoint responds with all the webhook subscribers associated with the X-Inveterate-Api-Key
included in the request. Note that this is not necessarily all of the webhook subscribers associated with a particular merchant, but a particular app.
GET
https://public.inveterateapi.com/webhooks
Get all webhook subscribers associated with this X-Inveterate-Api-Key
value.
DELETE
https://public.inveterateapi.com/webhooks
Customer cancellation events follow different patterns depending on the cause of cancellation (payment failure or customer request) and, for the latter, also the store's cancellation policy.
Please take a look at the trees of events below to see which cancellation lifecycle should be expected for a given customer, given the circumstances of their cancellation.
Let's say the customer's payment was due on Jan 10, it failed then. Two more follow-up attempts will be performed over the next two days. If these two fail as well, then the customer will be automatically cancelled and will lose access to their benefits.
Jan 10
Event trigger: customer_billing.attempt.failed
If enabled in merchant's messaging, user also gets an e-mail communicating them of the payment failure and informing them that they have three days to update their payment methods.
Jan 11
Event trigger: customer_billing.attempt.failed
Jan 12
Event trigger: customer_billing.attempt.failed
, customer.payment_failed
Customer gets cancelled and loses access to their benefits
if cancellation policy is immediately, customer status
: ACTIVE
-> CANCELLED
. Then customer.cancelled
event is triggered.
if cancellation policy is end of billing cycle, customer status
: ACTIVE
-> PENDING_CANCELLATION
. Then on the same day or the next day, customer gets cancelled and customer.cancelled
event is triggered.
For stores with cancellation policy set to immediate:
Customer requests cancellation
Event trigger: customer.cancellation_requested
Confirmation e-mail is sent, asking customer to confirm
If user confirms e-mail
Event trigger: customer.confirmed_cancellation
Customer gets cancelled and loses access to their benefits
status
: ACTIVE
-> CANCELLED
Email gets sent: Confirmed cancellation
Event trigger: customer.cancelled
Stores with cancellation policy set to end of billing cycle:
Customer requests cancellation
Event trigger: customer.cancellation_requested
Confirmation e-mail is sent, asking customer to confirm
If user confirms e-mail
Event trigger: customer.confirmed_cancellation
Customer update: status
from ACTIVE
-> PENDING_CANCELLATION
Email gets sent: Confirmed cancellation
When customer's billing cycle ends
Customer gets cancelled and loses access to their benefits
status
from PENDING_CANCELLATION
-> CANCELLED
Event trigger: customer.cancelled
X-Inveterate-Api-Key*
String
Required to access all protected endpoints on this API. Obtained from merchant's Inveterate dashboard.
callbackUrl*
String
The URL which will receive a POST request whenever an event should be passed from Inveterate to a subscriber.
name
String
Descriptive name to help identify the subscriber.
{
"success": true,
"data": {
"subscriber": {
"merchantId": "inveterate-staging-barefoot",
"id": "215498bda8d2169cc5db763377c0eda2",
"token": "fe10df8a669462ee3ae368b0bfe5f910",
"callbackUrl": "https://ztvfqj22g8.execute-api.us-east-1.amazonaws.com/prod/webhooks/callback-test",
"name": "Webhook Subscriber Endpoint Test",
"dateCreated": "2022-03-18T07:45:22.602Z",
"dateUpdated": "2022-03-18T07:45:22.602Z",
"createdByApp": "Default"
}
},
"errors": []
}
X-Inveterate-Api-Key*
String
Required to access all protected endpoints on this API. Obtained from merchant's Inveterate dashboard.
{
"success": true,
"data": {
"subscribers": [
{
"merchantId": "inveterate-staging-barefoot",
"id": "215498bda8d2169cc5db763377c0eda2",
"callbackUrl": "https://ztvfqj22g8.execute-api.us-east-1.amazonaws.com/prod/webhooks/callback-test",
"name": "Webhook Subscriber Endpoint Test",
"dateCreated": "2022-03-18T07:45:22.602Z",
"dateUpdated": "2022-03-18T07:45:22.602Z",
"createdByApp": "Default"
}
]
},
"errors": []
}
X-Inveterate-Api-Key*
String
Required to access all protected endpoints on this API. Obtained from merchant's Inveterate dashboard.
id*
String
The subscriber id.
{
"success": true,
"data": {
"subscriber": {}
},
"errors": []
}
Forwards a redemption request to the Inveterate backend. Returns the success status of the request against the backend service. Like the other endpoints that make requests against our backend, the changes may not take effect immediately.
The customer ID number.
Your private Inveterate API key.
POST /v2.0/storefront/members/{id}/credits/redemption HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
Returns all internal merchant information associated with the API key.
Your private Inveterate API key.
GET /v2.0/admin/merchant HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
This method forwards the cancellation creation request to our backend. Returns the success status of the request against backend service. Like the other endpoints that make requests against our backend, the changes may not take effect immediately.
The customer ID number.
POST /v2.0/storefront/members/{id}/cancellation HTTP/1.1
Host:
Accept: */*
{
"message": "text",
"data": {}
}
Returns all credits for one customer. API key is used to match the customer to your account for security reasons. Ensure that the customer ID is included in the request path.
The customer ID number.
Your private Inveterate API key.
GET /v2.0/storefront/members/{id}/credits?limit=text&lastCreditEntry=text HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
Returns all benefits for a given merchant. Merchant is pulled from the public API key for security reasons.
Your private Inveterate API key.
GET /v2.0/storefront/benefits HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
Returns a single benefit for a given merchant. Merchant is pulled from the public API key for security reasons. The benefit ID is the type of benefit. For a list of possible benefit types, see the default values in the schema list.
The benefit ID name/type.
Your private Inveterate API key.
GET /v2.0/storefront/benefits/{id} HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
A benefit
is represented as an object with the following structure:
{
enabled: Boolean,
creditAmount: Number,
icon: String,
displayOnLandingPage: Boolean,
description: String,
name: String,
type: String
}
GET
https://public.inveterateapi.com/benefits
{
"success": true,
"data": {
"benefits": [
{
"enabled": true,
"creditAmount": 10,
"icon": "https://d672z8ecdnbl.cloudfront.net/assets/iconography/custom/anniversary_credits.svg",
"displayOnLandingPage": true,
"description": "Earn credits every year, just for being a member of the program",
"name": "Anniversary Credits",
"type": "ANNIVERSARY_CREDITS"
},
{
"enabled": false,
"icon": "https://d672z8ecdnbl.cloudfront.net/assets/iconography/custom/discounts.svg",
"displayOnLandingPage": false,
"description": "Take advantage of exclusive member-only discounts on certain products.",
"name": "Member Only Discounts",
"type": "DISCOUNTS"
},
{
"enabled": false,
"icon": "https://d672z8ecdnbl.cloudfront.net/assets/iconography/custom/early_access.svg",
"displayOnLandingPage": false,
"description": "Get early access to new product releases before everyone else. Never run the risk of something being sold out!",
"name": "Early Access",
"type": "EARLY_ACCESS"
},
{
"enabled": false,
"icon": "https://d672z8ecdnbl.cloudfront.net/assets/iconography/custom/exclusive.svg",
"displayOnLandingPage": false,
"description": "Get access to products that are only eligible for purchase by members!",
"name": "Exclusive Access",
"type": "EXCLUSIVE"
},
{
"enabled": false,
"icon": "https://d672z8ecdnbl.cloudfront.net/assets/iconography/custom/shipping.svg",
"displayOnLandingPage": false,
"description": "Get free shipping on every order, every time.",
"name": "Free Shipping",
"type": "FREE_SHIPPING"
},
{
"enabled": false,
"icon": "https://d672z8ecdnbl.cloudfront.net/assets/iconography/custom/member_only_pricing.svg",
"displayOnLandingPage": false,
"description": "Take advantage of special member only pricing on certain products. Why pay full price if you don’t have to!",
"name": "Member Only Pricing",
"type": "MEMBER_ONLY_PRICING"
},
{
"enabled": true,
"creditAmount": 5,
"icon": "https://d672z8ecdnbl.cloudfront.net/assets/iconography/custom/referrals.svg",
"displayOnLandingPage": true,
"description": "Invite a friend to become a member and receive $5 when they sign up!",
"name": "Store Credits for Program Referral",
"type": "REFERRALS"
},
{
"enabled": false,
"creditAmount": 10,
"icon": "https://d672z8ecdnbl.cloudfront.net/assets/iconography/custom/store_credits.svg",
"displayOnLandingPage": false,
"description": "You’ll see $10 in store credit automatically hit your membership account every month.",
"name": "Recurring Store Credits",
"type": "SCHEDULED_STORE_CREDITS"
},
{
"enabled": true,
"creditAmount": 10,
"icon": "https://d672z8ecdnbl.cloudfront.net/assets/iconography/custom/store_credits.svg",
"displayOnLandingPage": true,
"description": "Receive $10 in store credits just for signing up for the program.",
"name": "Sign Up Store Credits",
"type": "SIGNUP_STORE_CREDITS"
}
],
"count": 9
},
"errors": []
}
Triggered when a customer joins a free tier in the loyalty program.
customer.joined.free_tier
{
"payload": {
"createdAt": "2025-05-30T11:23:12.195Z",
"tierId": "0d0c6284",
"merchantId": "inveterate",
"detail": {
"entryType": "FREE_SIGNUP",
"previousTierName": "PreviousTier",
"previousTierId": "6a538edc",
"tierName": "FREE"
},
"updatedAt": "2025-05-30T11:23:12.195Z",
"customerId": "7733576892547"
},
"metadata": {
"id": "a15fb599199de3eb84f4df329d9b1389",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.joined.free_tier",
"version": "2025-06",
"triggerredAt": "2025-05-30T11:23:12.888Z"
}
}
payload
createdAt
(string): ISO timestamp when the event was created
tierId
(string): Unique identifier for the tier the customer joined
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
updatedAt
(string): ISO timestamp when the event was last updated
detail
(object): Additional details about the tier transition
entryType
(string): How the customer joined (e.g., "FREE_SIGNUP")
previousTierName
(string): Name of the previous tier (if applicable)
previousTierId
(string): ID of the previous tier (if applicable)
tierName
(string): Name of the new tier
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
Returns a single member for a given merchant. Merchant is pulled from the public API key for security reasons.
The customer ID number which you would like to retrieve.
Your private Inveterate API key.
GET /v2.0/admin/members/{id} HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
Triggered when a customer joins a lifetime tier in the loyalty program through one-time purchase.
customer.joined.lifetime_tier
{
"payload": {
"createdAt": "2025-05-30T11:25:14.459Z",
"tierId": "d689602f",
"merchantId": "inveterate",
"detail": {
"entryType": "ONE_TIME_PURCHASE",
"tierName": "LIFETIME"
},
"updatedAt": "2025-05-30T11:25:14.459Z",
"customerId": "7733592490115"
},
"metadata": {
"id": "14d8ed9e66fa8eceb6a989cbaa9c8df5",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.joined.lifetime_tier",
"version": "2025-06",
"triggerredAt": "2025-05-30T11:25:15.202Z"
}
}
payload
createdAt
(string): ISO timestamp when the event was created
tierId
(string): Unique identifier for the lifetime tier the customer joined
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
updatedAt
(string): ISO timestamp when the event was last updated
detail
(object): Additional details about the tier entry
entryType
(string): How the customer joined (e.g., "ONE_TIME_PURCHASE")
tierName
(string): Name of the lifetime tier
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
Returns all tiers/segments for a given merchant. Merchant is pulled from the public API key for security reasons.
Whether or not to include benefits in the response.
Your private Inveterate API key.
Returns a single tier/segment for a given merchant. Merchant is pulled from the public API key for security reasons.
The tier segment ID.
Whether or not to include benefits in the response.
Your private Inveterate API key.
This endpoint will return all benefits for a merchant under a given tier. It will return an array of benefits. Each benefit will have a type
field that will identify the type of benefit.
The tier segment ID.
Your private Inveterate API key.
This endpoint will return one specific benefit given a benefit type and segment ID. Note that the benefit type is a string character. For a list of all benefit types, look at the default type value in each schema.
The tier segment ID.
The benefit type.
Your private Inveterate API key.
This endpoint will take a benefit type, segment ID, and any other values in the relevant schema and send a request to our backend to update the benefit with the new information. Keep in mind that, like with the POST method, this is a request against our backend. Thus, the effect will not be immediate.
The tier segment ID.
The benefit identification name/type.
Your private Inveterate API key.
Returns a single tier/segment for a given merchant and customer. Merchant is pulled from the public API key for security reasons.
The customer ID.
Whether or not to include benefits in the response.
Your private Inveterate API key.
This endpoint will return all benefits for a merchant under a given tier. It will return an array of benefits. Each benefit will have a type
field that will identify the type of benefit.
The customer ID.
Your private Inveterate API key.
Returns all campaigns belonging to the Tier the customer belongs to (customer identified with customerId
parameter)
The customer ID.
Your private Inveterate API key.
Returns all campaigns belonging to a specific Tier identified by its segmentId
The tier segment ID.
Your private Inveterate API key.
This endpoint will return all benefits for a merchant. It will return
an array of benefits. Each benefit will have a type
field that will
identify the type of benefit.
Your private Inveterate API key.
This endpoint will return one specific benefit given a benefit type. Note that the benefit type is a string character. For a list of all benefit types, look at the default type value in each schema.
The benefit type.
Your private Inveterate API key.
Forwards a request to our backend to delete a given benefit. Benefit will be identified by the benefit type field. For a list of all benefit types, take a look at each schema's default type value.
This is STRICTLY for deleting CUSTOM benefits. You cannot delete default benefits
via the Public API. Use your admin dashboard to disable default benefits.
The benefit identification name/type.
Your private Inveterate API key.
This endpoint will take a benefit type and any other values in the relevant schema and send a request to our backend to update the benefit. with the new information. Keep in mind that, like with the POST method, this is a request against our backend. Thus, the effect will not be immediate.
The benefit identification name/type.
Your private Inveterate API key.
GET /v2.0/admin/tiers HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
GET /v2.0/admin/tiers/{id} HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
GET /v2.0/admin/tiers/{id}/benefits HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
GET /v2.0/admin/tiers/{id}/benefits/{type} HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
PATCH /v2.0/admin/tiers/{id}/benefits/{type} HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Content-Type: application/json
Accept: */*
Content-Length: 92
{
"creditAmount": 1,
"name": "text",
"days": 1,
"description": "text",
"type": "SIGNUP_STORE_CREDITS"
}
{
"message": "text",
"data": {}
}
GET /v2.0/storefront/tiers/{id} HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
GET /v2.0/storefront/tiers/{id}/benefits HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
GET /v2.0/storefront/tiers/{id}/campaigns HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
GET /v2.0/admin/tiers/{id}/campaigns HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
GET /v2.0/admin/benefits HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
GET /v2.0/admin/benefits/{type} HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
DELETE /v2.0/admin/benefits/{type} HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
PATCH /v2.0/admin/benefits/{type} HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Content-Type: application/json
Accept: */*
Content-Length: 92
{
"creditAmount": 1,
"name": "text",
"days": 1,
"description": "text",
"type": "SIGNUP_STORE_CREDITS"
}
{
"message": "text",
"data": {}
}
A customer in the Inveterate system is anyone that has purchased an Inveterate subscription product from this merchant's store.
A customer
is represented as an object with the following structure:
{
accountState: String, // from Shopify
contractId: Number,
createdAt: String,
credit: Number,
customerId: String,
email: String,
firstName: String,
lastName: String,
orderCount: Number,
orderIds: Array[Number]
merchantId: String,
status: String, // status of Inveterate subscription
totalSpend: Number,
updatedAt: String
}
GET
https://public.inveterateapi.com/customers/{customerId}
Gets a single customer.
customerId*
String
The Shopify ID for a specific customer.
X-Inveterate-Api-Key*
String
Required to access all protected endpoints on this API. Obtained from merchant's Inveterate dashboard.
{
"data": {
"customer": {
"accountState": "ENABLED",
"contractId": 1234567890,
"createdAt": "2021-10-27T18:10:08.754Z",
...
}
}
"success": true,
"errors": []
}
{
"data": {}
"success": false,
"errors": [
"Invalid API key"
]
}
GET
https://api.inveterate.com/2022-01/customers
limit
Int
Amount of customers to return per request. Default is no limit. Max is 100.
lastCustomerId
Int
Used to determine the index offset of which customers to return.
X-Inveterate-Api-Key*
String
Required to access all protected endpoints on this API. Obtained from merchant's Inveterate dashboard.
{
"data": {
"customers": [
{
"accountState": "ENABLED",
"contractId": 1234567890,
"createdAt": "2021-10-27T18:10:08.754Z",
...
}
],
"lastCustomerId": "1234567890"
}
"success": true,
"errors": []
}
{
"data": {}
"success": false,
"errors": [
"Invalid API key"
]
}
Optionally using the limit
and lastCustomerId
query string parameters, you can "paginate" through the customer records returned.
For the first page, just add the limit
parameter. The response for this will include the lastCustomerId
, which needs to be added as a query string parameter to the request for page 2.
curl --location --request GET "${PUBLIC_API_URL}/customers?limit=1" \
--header "X-Inveterate-Api-Key: ${PUBLIC_API_KEY}"
{
"success": true,
"data": {
"customers": [
{
"lastName": "Alda",
"firstName": "Alan",
"customerId": "6082598928622"
}
],
"lastCustomerId": "6082598928622",
"limit": "1"
},
"errors": []
}
curl --location --request GET "${PUBLIC_API_URL}/customers?limit=1&lastCustomerId=6082598928622" \
--header "X-Inveterate-Api-Key: ${PUBLIC_API_KEY}"
{
"success": true,
"data": {
"customers": [
{
"lastName": "Bernanke",
"firstName": "Ben",
"customerId": "6082606694638"
}
],
"lastCustomerId": "6082606694638",
"limit": "1"
},
"errors": []
}
POST
https://public.inveterateapi.com/customers/{customerId}/cancel
Step 1 of the customer's subscription cancellation process. A successful request to this endpoint submits a customer cancellation request. Customer will receive an email with a link to confirm cancellation of their subscription.
merchantId*
String
{
"success": true,
"data": {
"cancelRequest": {
"merchantId": "inveterate-staging-barefoot",
"cancelToken": "c52157e9-2406-49d1-b374-583c92a3e3dd",
"customerId": "5574691979318",
"status": "INITIALIZED",
"createdAt": "2022-03-15T00:07:16.168Z",
"updatedAt": "2022-03-15T00:07:16.168Z"
}
},
"errors": []
}
{
"data": {}
"success": false,
"errors": [
"Invalid API key"
]
}
Triggered when a customer joins a paid tier in the loyalty program through subscription purchase.
customer.joined.paid_tier
{
"payload": {
"createdAt": "2025-05-30T10:17:56.959Z",
"tierId": "3a636361",
"merchantId": "inveterate",
"detail": {
"entryType": "SUBSCRIPTION_PURCHASE",
"tierName": "PAID"
},
"updatedAt": "2025-05-30T10:17:56.959Z",
"customerId": "7733540520067"
},
"metadata": {
"id": "f40a52b943e043a761df4f9e21364ccd",
"retryCount": 0,
"shopDomain": "inveterate.myshopify.com",
"topic": "customer.joined.paid_tier",
"version": "2025-06",
"triggerredAt": "2025-05-30T10:17:58.166Z"
}
}
payload
createdAt
(string): ISO timestamp when the event was created
tierId
(string): Unique identifier for the paid tier the customer joined
merchantId
(string): Merchant identifier
customerId
(string): Customer identifier
updatedAt
(string): ISO timestamp when the event was last updated
detail
(object): Additional details about the tier entry
entryType
(string): How the customer joined (e.g., "SUBSCRIPTION_PURCHASE")
tierName
(string): Name of the paid tier
metadata
id
(string): Unique event identifier
retryCount
(number): Number of retry attempts for this event
shopDomain
(string): Shopify domain of the merchant
topic
(string): Event topic name
version
(string): API version
triggerredAt
(string): ISO timestamp when the event was triggered
Returns all webhook subscriptions for the merchant
Your private Inveterate API key.
GET /v2.0/admin/webhook-subscriptions HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
Creates a new webhook subscription for the merchant
Your private Inveterate API key.
The subscription topic (will be used as sort key).
customer.joined.paid_tier
Possible values: The callback URL that will be called when one of the webhooks is triggered.
The subscription name.
POST /v2.0/admin/webhook-subscriptions HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Content-Type: application/json
Accept: */*
Content-Length: 72
{
"topic": "customer.joined.paid_tier",
"callbackUrl": "text",
"name": "text"
}
{
"message": "text",
"data": {}
}
Updates an existing webhook subscription configuration
Your private Inveterate API key.
The subscription topic to update.
customer.joined.paid_tier
Possible values: The callback URL that will be called when one of the webhooks is triggered.
The subscription name.
The subscription ID.
PUT /v2.0/admin/webhook-subscriptions HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Content-Type: application/json
Accept: */*
Content-Length: 84
{
"topic": "customer.joined.paid_tier",
"callbackUrl": "text",
"name": "text",
"id": "text"
}
{
"message": "text",
"data": {}
}
Removes an existing webhook subscription
Your private Inveterate API key.
The subscription topic to delete
customer.joined.paid_tier
Possible values: The subscription ID.
DELETE /v2.0/admin/webhook-subscriptions HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Content-Type: application/json
Accept: */*
Content-Length: 49
{
"topic": "customer.joined.paid_tier",
"id": "text"
}
{
"message": "text",
"data": {}
}
A list of our data schemas.
CreateMemberDto
merchantId*
string
customerId*
string
accountState*
string
anonymized*
boolean
contractId*
number
createdAt*
string
credit*
number
creditsEarned*
number
email*
string
firstName*
string
joinedAt*
string
lastCreditRedemptionAt*
string
lastName*
string
lastPurchaseAt*
string
notes*
string
numberOfCreditRedemptions*
number
orderCount*
number
orderIds*
[number]
paymentId*
number
phoneNumber*
string
referrals*
number
referredBy*
number
revenue*
number
status*
string
totalSpend*
number
updatedAt*
string
ResponseBodyDto
message*
string
The message associated with the response. Generally, the message only confirms the requested action. In the case of errors, the message will give insight into the source of the error.
data*
The data associated with the response. Data is only returned from errors if the error originates from our backend to give further insight into the nature of the error.
UpdateMemberDto
firstName*
string
The customer's first name.
lastName*
string
The customer's last name.
notes*
string
Internal notes for this customer. Only viewable by the merchant.
phoneNumber*
string
The customer's phone number.
CreateCreditDto
amount*
number minimum: 1
The amount of credits to add to the customer's account.
SignupStoreCreditsDto
creditAmount*
number
The amount to be awarded upon sign-up.
name*
string
The name (appearance only) of this benefit.
days*
number
The number of days to delay the credit award.
description*
string
The description of this benefit (appearance only).
type*
This is an internal identifier, leave default.
RecurringStoreCreditsDto
creditAmount*
number
The amount to be awarded each recurrence.
name*
string
The name (appearance only) of this benefit.
description*
string
The description of this benefit (appearance only).
frequency*
number
How often (in days) you want to award this credit.
type*
This is an internal identifier, leave default.
CreditsforOrdersDto
internalTitle*
string
The internal identifier, leave default.
type*
This is an internal identifier, leave default.
description:
This is an internal identifier, leave default.
name*
string
The name (appearance only) of this benefit.
description*
string
The description of this benefit (appearance only).
enabled*
boolean
Whether this benefit is enabled or not.
rule*
string
Which credit rule: "PERCENTAGE_BACK_ON_PURCHASE", "EARN_EVERY_ORDER", or "SPEND_AND_EARN".
Enum: [ PERCENTAGE_BACK_ON_PURCHASE, EARN_EVERY_ORDER, SPEND_AND_EARN ]
rewardValue*
number
The amount of credits (or percent) to give as an award.
excludeInveterateMembershipProducts*
boolean
Whether or not to include the membership product for credit.
minimumPurchaseAmount*
number
The minimum individual purchase amount to award credit for orders.
maximumRewardValue*
string
The discount code to use for this benefit.
allowRefunds*
boolean
Whether or not this benefit is displayed on the landing page.
appliesTo*
string
Which products or collections this benefit applies to: "ALL_PRODUCTS", "SPECIFIC_PRODUCTS", or "SPECIFIC_COLLECTIONS".
Enum: [ ALL_PRODUCTS, SPECIFIC_PRODUCTS, SPECIFIC_COLLECTIONS ]
applicableTo*
If appliesTo is either of the latter two values, this is a string array of Shopify Product IDs or Collection IDs (i.e. "gid://shopify/Collection/266717724758").
string]
AnniversaryCreditsDto
creditAmount*
number
The amount of credits to award on anniversary.
name*
string
The name (appearance only) of this benefit.
description*
string
The description of this benefit (appearance only).
type*
This is an internal identifier, leave default.
StoreCreditsforReferralDto
creditAmount*
number
The amount of credits to award on referral.
name*
string
The name (appearance only) of this benefit.
description*
string
The description of this benefit (appearance only).
type*
This is an internal identifier, leave default.
FreeShippingDto
shippingType*
string
Which shipping type: "DISCOUNT_CODE" or "SCRIPT".
Enum: [ DISCOUNT_CODE, SCRIPT ]
code*
string
The name (appearance only) of this benefit.
minRequirements*
string
Which minumum requirements: "ITEM_QUANTITY", "PURCHASE_AMOUNT", or "NONE".
Enum: [ ITEM_QUANTITY, PURCHASE_AMOUNT, NONE ]
isRatesExcluded*
boolean
Whether or not to include purchases with shipping rates over a certain value.
maximumShippingPrice*
number
The maximum shipping rate over which shipping is not free (only with previous value true).
minimumQuantity*
number
If minRequirements is "ITEM_QUANTITY", include this field to indicate minimum number of items.
minimumSubtotal*
number
If minRequirements is "PURCHASE_AMOUNT", include this field to indicate the minumum purchase amount.
countryType*
string
Which country type: "ALL" or "SPECIFIC".
Enum: [ ALL, SPECIFIC ]
countries*
If previous value is "SPECIFIC", this field contains the specific countries in the format: { "label": "United States", "value": "United States" }
type*
This is an internal identifier, leave default.
description:
This is an internal identifier, leave default.
MemberOnlyDiscountDto
name*
string
The name (appearance only) of this benefit.
description*
string
The description of this benefit (appearance).
type*
This is an internal identifier, leave default.
description:
This is an internal identifier, leave default.
SignupDiscountDto
name*
string
The name (appearance only) of this benefit.
description*
string
The description of this benefit (appearance).
discountType*
string
Which discount type: "percentage" or "fixed".
Enum: [ percentage, fixed ]
value*
number
The fixed or percentage award value.
collectionIds*
If using collections, this is a string array of Shopify Collection IDs (i.e. "gid://shopify/Collection/266717724758").
string
productIds*
If using products, this is a string array of Shopify Product IDs (i.e. "gid://shopify/Product/266717724758").
string
minimumSubtotal*
number
The minimum subtotal for an individual purchase to qualify (null if using quantity).
minimumQuantity*
number
The minimum quantity of items in an individual purchase to qualify (null if using subtotal).
oneUsePerCustomer*
boolean
Whether or not this discount is single use per customer.
hasExpiration*
boolean
Whether or not this discount expires.
expirationDays*
number
If the previous value is true, this is the quantity, in days, before this discount expires.
type*
This is an internal identifier, leave default.
MemberPricingDto
name*
string
The name (appearance only) of this benefit.
description*
string
The description of this benefit (appearance).
collectionId*
string
The Shopify collection ID link to apply this benefit to.
defaultDiscountPercentage*
number
The discount in pricing to apply to the collection.
type*
This is an internal identifier, leave default.
EarlyAccessCampaignDto
name*
string
The name (appearance only) of this benefit.
collectionIds*
The Shopify collection IDs to apply this benefit to.
startDate*
string
The Shopify discount code ID to apply to the collection.
endDate*
string
The end date that takes the format: YYYY-MM-DD HH:MM:SS +00:00
WebhookDto
merchantId*
string
The ID of the merchant that owns this webhook.
id*
string
The ID of the webhook.
createdByApp*
string
The entity that is requesting the webhook creation.
dateCreated*
string
The date the webhook was created.
dateUpdated*
string
The date the webhook was last updated.
name*
string
The name associated with the callback URL.
callbackUrl*
string
The callback URL that will be called when one of the webhooks is triggered.
token*
string
The token associated with the webhook.
Returns all members for a given merchant. Merchant is pulled from the public API key for security reasons. Pagination is supported by passing limit and lastCustomerId values as query parameters. You will get a lastCustomerId value in the response of the previous request, which can be used for the next.
Your private Inveterate API key.
This endpoint is used to create a free tier member. You can also provide a credit value to add credits to the new members account.
The overrideSpendThreshold
parameter allows you to add customers to a spend based tier, and the keepInSpendBasedTier
parameter
ensures that the member won't be downgraded if they don't hit the spend minimum.
NOTE: This endpoint will downgrade a customer specified to a lower tier if that is the tier provided to the endpoint!
Your private Inveterate API key.
The customerId to add to the specified free tier.
The signify whether or not the customer was referred. NOTE: NOT to be used to indicate the referring customer.
The segmentId of the tier you want to add this customer to.
Whether or not to override the spend required to add a customer to a spend based tier.
Whether or not you want to keep this customer in the spend based tier despite not meeting the spend threshold.
Especially for member creation requests, if you would like to add some credits to the specified customer.
The customer's date of birth in YYYY-MM-DD format, e.g "1988-04-01"
This endpoint is used to update a member. It takes a member ID and uses your public API key to match the customer to your account. As of now, all fields in the update schema are required, so it is not possible to update a single field at a time.
The customer ID number which you would like to update.
Your private Inveterate API key.
The customer's first name.
The customer's last name.
Internal notes for this customer. Only viewable by the merchant.
The customer's phone number.
The customer's date of birth in YYYY-MM-DD format, e.g "1988-04-01"
Returns all member data for a given member that is a part of your store. Merchant is pulled from the public API key for security reasons. Make sure to include the customer ID in the request path.
The customer ID number.
Your private Inveterate API key.
Returns all credits for one customer. API key is used to match the customer to your account for security reasons. Ensure that the customer ID is included in the request path. Pagination is supported by passing limit and lastCreditEntry values as query parameters. You will get a lastCreditEntry value in the response of the previous request, which can be used for the next. Ensure that the lastCreditEntry value passed to the server is encoded.
The customer ID number.
The number of credits to return (for pagination).
The last credit entry from the previous request.
Your private Inveterate API key.
GET /v2.0/admin/members?limit=text&lastCustomerId=text HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
POST /v2.0/admin/members HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Content-Type: application/json
Accept: */*
Content-Length: 147
{
"customerId": "text",
"referrals": "text",
"segmentId": "text",
"overrideSpendThreshold": true,
"keepInSpendBasedTier": true,
"credits": 1,
"birthday": "text"
}
{
"message": "text",
"data": {}
}
PATCH /v2.0/admin/members/{id} HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Content-Type: application/json
Accept: */*
Content-Length: 92
{
"firstName": "text",
"lastName": "text",
"notes": "text",
"phoneNumber": "text",
"birthday": "text"
}
{
"message": "text",
"data": {}
}
GET /v2.0/storefront/members/{id} HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
GET /v2.0/admin/members/{id}/credits HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Accept: */*
{
"message": "text",
"data": {}
}
This method forwards the credit creation request to our backend. Returns the success status of the request against backend service. Like the other endpoints that make requests against our backend, the changes may not take effect immediately.
The customer ID number.
Your private Inveterate API key.
The amount of credits to be added to or removed from the customer's account. It can't be zero
Optional note to be associated with this credit transaction
POST /v2.0/admin/members/{id}/credits HTTP/1.1
Host:
X-Inveterate-Api-Key: text
Content-Type: application/json
Accept: */*
Content-Length: 26
{
"amount": 1,
"note": "text"
}
{
"message": "text",
"data": {}
}