Only this pageAll pages
Powered by GitBook
1 of 54

Dev

Loading...

API Reference Docs

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...

Stack Reference Docs

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Inveterate Dev Docs

Welcome to the Inveterate developer documentation. Here we'll cover our API, API SDK and Frontend SDK.

Get Started

Get started by hopping into the documentation that is most necessary for you:

Public API 2.0 Reference
[LEGACY] Public API Reference
Storefront

Public API 2.0 Reference

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.

Why Switch?

  1. Massive performance improvements: most if not all endpoints are operating anywhere between 1.5x and 8x faster than our previous implementation.

  2. Stricter internal security.

  3. Support for Tiers

  4. A roadmap that will allow you to do many new and powerful things with our Public API.

  5. Public API v1 will sunset in May of 2024!

Authentication

API Keys are private and should not be shared or exposed on the front end.

Using API Key in Requests

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.

API URL

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.

Example Get Request

curl -X GET "https://public.inveterateapi.com/v2.0/merchant"
-H "X-Inveterate-Api-Key: {api_key}"

Admin vs Storefront

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.

Redemption

Create a credit redemption request for a member.

Webhooks

customer.payment_succeeded

Triggered when a customer's payment is successfully processed.

customer.payment_succeeded

Payload Structure

{
  "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 Fields

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

Storefront

Our storefront-authenticated endpoints.

Members

Member accessing and altering endpoints.

Merchant

Get your merchant data. Serves as a good health check for our services and your API key/access.

Tiers

These endpoints only work for merchants with tiers enabled. Access benefits via this set of endpoints.

Benefits

Overview

Get, create, update and delete webhook subscriptions. Use these to build third-party integrations.

Cancellation

Create a cancellation request for a member.

Tiers

These endpoints only work for merchants with tiers enabled. Access benefits via this set of endpoints.

Benefits

Campaigns

Credits

Get credits for a specific member.

Customizations

This section contains information about how to customize your storefront UI.

customer.cancelled

Triggered when a customer's subscription is cancelled.

customer.cancelled

Payload Structure

Payload Fields

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

[LEGACY] Public API Reference

The Rest API allows you to build a highly custom paid-membership program on your Shopify storefront.

NOTE: With the release of Public API v2, Public API v1 will be sunset in May of 2024!

Find the v2 reference .

Authentication

API Keys are private and should not be shared or exposed on the front end.

Using API Key in Requests

Include your API key as an X-Inveterate-Api-Key header on all API endpoint requests.

Requirements

All API requests utilize https://public.inveterateapi.com/ as the base URL.

Example Get Request

Reference Shortcuts

Members

Member get. Includes more member actions in sub-directories.

Campaigns API

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:

Endpoints & Methods

Get all campaigns

GET https://public.inveterateapi.com/campaigns

Add To Cart Button
{
  "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"
  }
}

Topics

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

  • Account

    • customer.joined.paid_tier

    • customer.joined.free_tier

    • customer.joined.free_trial

    • customer.joined.lifetime_tier

    • customer.changed_tier

    • customer.updated

  • Orders and Payments

    • customer.ordered

    • customer.payment_succeeded

    • customer.payment_failed

    • customer_billing.attempt.failed

    • customer.payment_method.changed

  • Credit

    • customer.credits.updated

    • customer.credits.expired

  • Cancellations

    • customer.cancelled

    • customer.pending_cancellation

customer.joined.free_trial

Triggered when a customer joins a free trial tier in the loyalty program.

customer.joined.free_trial

Payload Structure

{
  "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 Fields

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

customer.changed_tier

Triggered when a customer changes from one tier to another in the loyalty program.

customer.changed_tier

Payload Structure

{
  "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 Fields

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

customer.payment_methods.updated

Triggered when a customer's payment method is updated.

customer.payment_methods.updated

Payload Structure

{
  "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 Fields

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

Customer Metafields

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.

(Inveterate) Balance

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.

(Inveterate) Next Payment

This filed displays the next payment date for the customer's membership. It is stored in ISO format.

(Inveterate) Referrals

This field displays a list of all completed referrals made by the member.

inveterate.payment_amount

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
}
here
Benefits API
Campaigns API
Customers API
Merchant API
Webhooks
Free tiers API

Benefits

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.

customer_billing.attempt.failed

Triggered when a billing attempt fails but there may be more retry attempts remaining.

customer_billing.attempt.failed

Payload Structure

Payload Fields

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

customer.payment_failed

Triggered when a customer's payment has failed after all retry attempts have been exhausted.

customer.payment_failed

Payload Structure

Payload Fields

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

customer.credits.updated

Triggered when a customer's credit balance is updated (credits earned or redeemed).

customer.credits.updated

Payload Structure

Payload Fields

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

customer.pending_cancellation

Triggered when a customer has requested cancellation but the cancellation is scheduled for a future date.

customer.pending_cancellation

Payload Structure

Payload Fields

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

Landing Page

This is an advanced guide.

Dealing with Slide Out Cart Behavior

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:

  1. Add the membership to cart (if it's not already in cart)

  2. Update add to cart buttons on the page with a success state

  3. Refresh the page with ?cart-updated=true added to the URL

  4. 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 Script Tag in <head>

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.

Make Update in Your JavaScript

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.

Storefront

On your storefront, we automatically add and update 2 files:

  • inveterate-theme.liquid

  • inveterate-checkout.liquid

See for more information about this.

What is the Inveterate Storefront code?

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.

The inveterate object

All 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);

customer.ordered

Triggered when a customer places an order.

customer.ordered

Payload Structure

{
  "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 Fields

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

Properties

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
Snippets
Properties
{
  "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());

customer.updated

Triggered when a customer's information is updated.

customer.updated

Payload Structure

{
  "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 Fields

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

Admin

Our admin endpoints.

Campaigns

Credits

Get and create credit requests.

Free tiers API

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?,
}

Sign up customer for free tier

POST https://public.inveterateapi.com/signup-free-tier

Request Body

Name
Type
Description

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.

Add To Cart Button

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.

Where do I find the selling plan ID for my membership product?

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):

Inveterate object in browser console.

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:

Object of subscription product in browser console.

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:

Selling plan ID in browser console

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.

(Optional) _inveterate_subscription Property

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.

How To Set Up ATCs For Tiers

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.

Free Gift With Signup Benefit Setup

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
      }
    }
  ]}),

Benefits

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.

Credits API

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;
}

Endpoints & Methods

Get a customers credit ledger history

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

Path Parameters

Name
Type
Description

customerId*

Number

The customer ID which you intend to pull the data of.

Headers

Name
Type
Description

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"
}

Add credits to a customer

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

Path Parameters

Name
Type
Description

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.

Headers

Name
Type
Description

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.

Create a request to redeem credits

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).

Request Body

Name
Type
Description

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.

email

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.

customer.credits.expired

Triggered when a customer's credits have expired and are removed from their balance.

customer.credits.expired

Payload Structure

{
  "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 Fields

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

Merchant API

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
}

Endpoints & Methods

Get merchant

GET https://public.inveterateapi.com/merchant

Gets merchant data.

Headers

Name
Type
Description

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"
  ]
}

Webhooks

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.

Webhooks 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

Create a Webhook Subscriber

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.

Create Webhook Subscriber

POST https://public.inveterateapi.com/webhooks

Headers

Name
Type
Description

Request Body

Name
Type
Description

Get Webhook Subscribers

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 Webhook Subscribers

GET https://public.inveterateapi.com/webhooks

Get all webhook subscribers associated with this X-Inveterate-Api-Key value.

Headers

Name
Type
Description

Delete Webhook Subscriber

DELETE https://public.inveterateapi.com/webhooks

Headers

Name
Type
Description

Request Body

Name
Type
Description

Anecdote: Cancellation Events

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.

Event Timeline: Cancellation due to payment failure

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.

Event Timelines: Cancellation due to customer request

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": []
}
more details below.
post

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.

Path parameters
idstringRequired

The customer ID number.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
201
Returned upon successful request made to our backend. Requests that return this code may take a small amount of time after successful API return to fully update.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
post
POST /v2.0/storefront/members/{id}/credits/redemption HTTP/1.1
Host: 
X-Inveterate-Api-Key: text
Accept: */*
{
  "message": "text",
  "data": {}
}
get

Returns all internal merchant information associated with the API key.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
GET /v2.0/admin/merchant HTTP/1.1
Host: 
X-Inveterate-Api-Key: text
Accept: */*
{
  "message": "text",
  "data": {}
}
post

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.

Path parameters
idstringRequired

The customer ID number.

Responses
201
Returned upon successful request made to our backend. Requests that return this code may take a small amount of time after successful API return to fully update.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
post
POST /v2.0/storefront/members/{id}/cancellation HTTP/1.1
Host: 
Accept: */*
{
  "message": "text",
  "data": {}
}
get

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.

Path parameters
idstringRequired

The customer ID number.

Query parameters
limitstringRequired
lastCreditEntrystringRequired
Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
GET /v2.0/storefront/members/{id}/credits?limit=text&lastCreditEntry=text HTTP/1.1
Host: 
X-Inveterate-Api-Key: text
Accept: */*
{
  "message": "text",
  "data": {}
}
get

Returns all benefits for a given merchant. Merchant is pulled from the public API key for security reasons.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
GET /v2.0/storefront/benefits HTTP/1.1
Host: 
X-Inveterate-Api-Key: text
Accept: */*
{
  "message": "text",
  "data": {}
}
get

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.

Path parameters
idstringRequired

The benefit ID name/type.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
GET /v2.0/storefront/benefits/{id} HTTP/1.1
Host: 
X-Inveterate-Api-Key: text
Accept: */*
{
  "message": "text",
  "data": {}
}

Benefits API

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
}

When making a request to the Benefits API, all benefits will be returned as objects within a benefits array.

Endpoints & Methods

Get all benefits

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": []
}

customer.joined.free_tier

Triggered when a customer joins a free tier in the loyalty program.

customer.joined.free_tier

Payload Structure

{
  "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 Fields

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

get

Returns a single member for a given merchant. Merchant is pulled from the public API key for security reasons.

Path parameters
idstringRequired

The customer ID number which you would like to retrieve.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
GET /v2.0/admin/members/{id} HTTP/1.1
Host: 
X-Inveterate-Api-Key: text
Accept: */*
{
  "message": "text",
  "data": {}
}

customer.joined.lifetime_tier

Triggered when a customer joins a lifetime tier in the loyalty program through one-time purchase.

customer.joined.lifetime_tier

Payload Structure

{
  "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 Fields

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

get

Returns all tiers/segments for a given merchant. Merchant is pulled from the public API key for security reasons.

Query parameters
includeBenefitsbooleanOptional

Whether or not to include benefits in the response.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
get

Returns a single tier/segment for a given merchant. Merchant is pulled from the public API key for security reasons.

Path parameters
idstringRequired

The tier segment ID.

Query parameters
includeBenefitsbooleanOptional

Whether or not to include benefits in the response.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
get

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.

Path parameters
idstringRequired

The tier segment ID.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
get

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.

Path parameters
idstringRequired

The tier segment ID.

typestringRequired

The benefit type.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
patch

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.

Path parameters
idstringRequired

The tier segment ID.

typestringRequired

The benefit identification name/type.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Body
one ofOptional
or
or
or
or
or
or
or
or
or
Responses
201
Returned upon successful request made to our backend. Requests that return this code may take a small amount of time after successful API return to fully update.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
patch
get

Returns a single tier/segment for a given merchant and customer. Merchant is pulled from the public API key for security reasons.

Path parameters
idstringRequired

The customer ID.

Query parameters
includeBenefitsbooleanOptional

Whether or not to include benefits in the response.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
get

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.

Path parameters
idstringRequired

The customer ID.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
get

Returns all campaigns belonging to the Tier the customer belongs to (customer identified with customerId parameter)

Path parameters
idstringRequired

The customer ID.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
get

Returns all campaigns belonging to a specific Tier identified by its segmentId

Path parameters
idstringRequired

The tier segment ID.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
get

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.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
get

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.

Path parameters
typestringRequired

The benefit type.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
delete

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.
Path parameters
typestringRequired

The benefit identification name/type.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
201
Returned upon successful request made to our backend. Requests that return this code may take a small amount of time after successful API return to fully update.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
delete
patch

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.

Path parameters
typestringRequired

The benefit identification name/type.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Body
one ofOptional
or
or
or
or
or
or
or
or
or
Responses
201
Returned upon successful request made to our backend. Requests that return this code may take a small amount of time after successful API return to fully update.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
patch
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": {}
}

Customers API

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
}

Endpoints & Methods

Get a single customer

GET https://public.inveterateapi.com/customers/{customerId}

Gets a single customer.

Path Parameters

Name
Type
Description

customerId*

String

The Shopify ID for a specific customer.

Headers

Name
Type
Description

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 all customers

GET https://api.inveterate.com/2022-01/customers

Query Parameters

Name
Type
Description

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.

Headers

Name
Type
Description

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"
  ]
}

Get Customers (Paginated)

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.

Page 1 request example

curl --location --request GET "${PUBLIC_API_URL}/customers?limit=1" \
--header "X-Inveterate-Api-Key: ${PUBLIC_API_KEY}"

Page 1 response example

{
    "success": true,
    "data": {
        "customers": [
            {
                "lastName": "Alda",
                "firstName": "Alan",
                "customerId": "6082598928622"
            }
        ],
        "lastCustomerId": "6082598928622",
        "limit": "1"
    },
    "errors": []
}

Page 2 request example

curl --location --request GET "${PUBLIC_API_URL}/customers?limit=1&lastCustomerId=6082598928622" \
--header "X-Inveterate-Api-Key: ${PUBLIC_API_KEY}"

Page 2 response example

{
    "success": true,
    "data": {
        "customers": [
            {
                "lastName": "Bernanke",
                "firstName": "Ben",
                "customerId": "6082606694638"
            }
        ],
        "lastCustomerId": "6082606694638",
        "limit": "1"
    },
    "errors": []
}

Cancel Customer Subscription

Request customer cancellation

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.

Request Body

Name
Type
Description

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"
  ]
}

customer.joined.paid_tier

Triggered when a customer joins a paid tier in the loyalty program through subscription purchase.

customer.joined.paid_tier

Payload Structure

{
  "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 Fields

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

get

Returns all webhook subscriptions for the merchant

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
GET /v2.0/admin/webhook-subscriptions HTTP/1.1
Host: 
X-Inveterate-Api-Key: text
Accept: */*
{
  "message": "text",
  "data": {}
}
post

Creates a new webhook subscription for the merchant

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Body
topicstring · enumRequired

The subscription topic (will be used as sort key).

Example: customer.joined.paid_tierPossible values:
callbackUrlstringRequired

The callback URL that will be called when one of the webhooks is triggered.

namestringRequired

The subscription name.

Responses
201
Returned upon successful request made to our backend. Requests that return this code may take a small amount of time after successful API return to fully update.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
post
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": {}
}
put

Updates an existing webhook subscription configuration

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Body
topicstring · enumRequired

The subscription topic to update.

Example: customer.joined.paid_tierPossible values:
callbackUrlstringOptional

The callback URL that will be called when one of the webhooks is triggered.

namestringOptional

The subscription name.

idstringRequired

The subscription ID.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
put
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": {}
}
delete

Removes an existing webhook subscription

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Body
topicstring · enumRequired

The subscription topic to delete

Example: customer.joined.paid_tierPossible values:
idstringRequired

The subscription ID.

Responses
201
Returned upon successful request made to our backend. Requests that return this code may take a small amount of time after successful API return to fully update.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
delete
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": {}
}

Schemas

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.

get

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.

Query parameters
limitstringRequired
lastCustomerIdstringRequired
Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
post

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!

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Body
customerIdstringRequired

The customerId to add to the specified free tier.

referralsstringRequired

The signify whether or not the customer was referred. NOTE: NOT to be used to indicate the referring customer.

segmentIdstringRequired

The segmentId of the tier you want to add this customer to.

overrideSpendThresholdbooleanRequired

Whether or not to override the spend required to add a customer to a spend based tier.

keepInSpendBasedTierbooleanRequired

Whether or not you want to keep this customer in the spend based tier despite not meeting the spend threshold.

creditsnumber · min: 1Required

Especially for member creation requests, if you would like to add some credits to the specified customer.

birthdaystringRequired

The customer's date of birth in YYYY-MM-DD format, e.g "1988-04-01"

Responses
201
Returned upon successful request made to our backend. Requests that return this code may take a small amount of time after successful API return to fully update.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
post
patch

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.

Path parameters
idstringRequired

The customer ID number which you would like to update.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Body
firstNamestringRequired

The customer's first name.

lastNamestringRequired

The customer's last name.

notesstringRequired

Internal notes for this customer. Only viewable by the merchant.

phoneNumberstringRequired

The customer's phone number.

birthdaystringRequired

The customer's date of birth in YYYY-MM-DD format, e.g "1988-04-01"

Responses
201
Returned upon successful request made to our backend. Requests that return this code may take a small amount of time after successful API return to fully update.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
patch
get

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.

Path parameters
idstringRequired

The customer ID number.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
get

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.

Path parameters
idstringRequired

The customer ID number.

Query parameters
limitnumberOptional

The number of credits to return (for pagination).

lastCreditEntrystringOptional

The last credit entry from the previous request.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Responses
200
Returned upon successful direct action to our database. Action is immediate.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
get
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": {}
}
post

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.

Path parameters
idstringRequired

The customer ID number.

Header parameters
X-Inveterate-Api-KeystringRequired

Your private Inveterate API key.

Body
amountnumberRequired

The amount of credits to be added to or removed from the customer's account. It can't be zero

notestringOptional

Optional note to be associated with this credit transaction

Responses
201
Returned upon successful request made to our backend. Requests that return this code may take a small amount of time after successful API return to fully update.
application/json
400
Returned upon a malformed request. Check your API key, URL parameters, and body parameters when this error is returned. Generally, if you see this error, that also means NO action was taken on our backend.
application/json
500
Returned for all other errors. Generally these come from our backend. Some multipart functions may execute somewhat and then fail, causing some data to be updated.
application/json
post
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": {}
}