#Loyalty events
GET /loyalty-events
List the custom events your systems have reported, newest first by default. Filter by name, by properties.<name>, or by the customer through customer.id or customer.email. Supports search, filtering and cursor pagination.
Requires the loyalty:read permission.
Query parameters
limitnumberThe number of records to return.
cursorstringA pagination cursor. Fetch the next page by passing the nextCursor value from the previous response.
sortoccurredAt | -occurredAt | createdAt | -createdAtThe sort order. Prefix a field with - to sort descending. Defaults to -occurredAt.
searchstringA free-text search term. Every word has to match, from the start of a word, in any order and ignoring case and accents, against the record's most identifying fields. Combined with filter using AND.
filterstringA JSON-encoded filter document, for example {"createdAt":{"$gte":"2025-01-01T00:00:00Z"}}. Filterable fields: id, name, value, properties, idempotencyKey, occurredAt, createdAt, customer.id, customer.email, customer.firstName, customer.lastName, customer.metadata, customer.emailOptOut, customer.emailOptOutSource, customer.createdAt. See Filtering for the syntax.
includestringA comma-separated list of extra fields to compute and return. Each one costs an additional query, so ask only for what you need. Available: customer.
curl \
"https://your-store.meisei.app/api/loyalty-events" \
-H "Authorization: Bearer sk_YOUR_SECRET_KEY"import { client } from "@meisei/api/admin/client"
import { getLoyaltyEvents } from "@meisei/api/admin"
client.setConfig({
baseUrl: "https://your-store.meisei.app/api",
headers: { Authorization: "Bearer sk_YOUR_SECRET_KEY" },
})
const { data, error } = await getLoyaltyEvents()require "meisei"
meisei = Meisei::Client.new(
secret_key: "sk_YOUR_SECRET_KEY",
base_url: "https://your-store.meisei.app/api",
)
page = meisei.loyalty_events.listfrom meisei import Client
meisei = Client(
secret_key="sk_YOUR_SECRET_KEY",
base_url="https://your-store.meisei.app/api",
)
page = meisei.loyalty_events.list(){
"data": [
{
"id": "A4Ws1igz",
"customerId": "A4Ws1igz",
"name": "string",
"value": 0,
"properties": "...",
"idempotencyKey": "string",
"occurredAt": "2025-01-15T09:30:00Z",
"createdAt": "2025-01-15T09:30:00Z",
"customer": {
"id": "...",
"email": "...",
"phone": "...",
"firstName": "...",
"lastName": "...",
"country": "...",
"metadata": "...",
"notes": "...",
"emailOptOut": "...",
"emailOptOutAt": "...",
"emailOptOutSource": "...",
"createdAt": "...",
"updatedAt": "..."
}
}
],
"nextCursor": "string"
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the event.",
"idCodec": "sqid"
},
"customerId": {
"type": "string",
"description": "The customer the event is about.",
"idCodec": "sqid"
},
"name": {
"type": "string",
"description": "The event's name, such as `review.written`."
},
"value": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "How many units the event is worth, as sent. Null when it carried none."
},
"properties": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "string",
"maxLength": 500
},
{
"type": "number"
},
{
"type": "boolean"
}
]
},
"description": "Free-form facts about the event, as a flat object of strings, numbers and booleans, such as `{ \"rating\": 5, \"channel\": \"store\" }`. Rules can require conditions on them."
},
"idempotencyKey": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Your own identifier for the event, as sent. Null when it carried none."
},
"occurredAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the event happened."
},
"createdAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When Meisei recorded the event."
},
"customer": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the customer.",
"idCodec": "sqid"
},
"email": {
"type": "string",
"format": "email",
"pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
"description": "The customer's email address, unique within the organization."
},
"phone": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The customer's phone number in E.164 format."
},
"firstName": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The customer's first name."
},
"lastName": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The customer's last name."
},
"country": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The customer's country, as an ISO 3166-1 code."
},
"metadata": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"description": "A metadata value: a string, a number, true or false, or a list of strings. A key with a metadata definition holds the type its definition names."
},
"description": "Key/value pairs for your own data. Keys you define with `/metadata-definitions` are typed and validated; any other key is free-form. Individual keys are filterable with a dot path, for example `metadata.category`."
},
"notes": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Internal notes about the customer. Never shown to them."
},
"emailOptOut": {
"type": "boolean",
"description": "Whether the customer has opted out of marketing email. They still receive mail they asked for, such as a wishlist they shared themselves."
},
"emailOptOutAt": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
},
{
"type": "null"
}
],
"description": "When the opt-out was recorded. Null while the customer is still subscribed."
},
"emailOptOutSource": {
"anyOf": [
{
"type": "string",
"enum": ["customer", "merchant", "import", "shopify"],
"description": "Where the opt-out came from."
},
{
"type": "null"
}
],
"description": "Where the opt-out came from: `customer` (they opted out themselves, through an unsubscribe link or your integration), `merchant`, `import` or `shopify`. Null while the customer is still subscribed."
},
"createdAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the customer was first created in Meisei."
},
"updatedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the customer was last changed."
}
},
"required": [
"id",
"email",
"phone",
"firstName",
"lastName",
"country",
"metadata",
"notes",
"emailOptOut",
"emailOptOutAt",
"emailOptOutSource",
"createdAt",
"updatedAt"
],
"additionalProperties": false,
"description": "The customer the event is about."
}
},
"required": [
"id",
"customerId",
"name",
"value",
"properties",
"idempotencyKey",
"occurredAt",
"createdAt"
],
"additionalProperties": false
},
"description": "The page of records, in the requested sort order."
},
"nextCursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Pass this back as `cursor` to fetch the next page. Null once the last page has been returned."
}
},
"required": ["data", "nextCursor"],
"additionalProperties": false
}POST /loyalty-events
Report something your own systems saw about a customer, as a named event with an optional value and properties. Every rule whose trigger listens for the name decides what the customer earns: it can require conditions on the properties, fire on every Nth event, or cap how often it fires per day, week or month. The event is recorded even when no rule listens for it yet. Rules run on a queue rather than inline, so a 202 means the event was recorded, not that anything was awarded yet. Sending the same idempotencyKey again for the same customer returns the original event and awards nothing a second time. Programs that are paused are reported back rather than queued.
Requires the loyalty:write permission.
Body parameters
namestringrequiredThe event's name, such as review.written. Letters, digits, periods, underscores, colons and hyphens, up to 100 characters.
customerIdstringThe customer the event is about. Send this or customerEmail, not both.
customerEmailstring (email)The email address of the customer the event is about, as Meisei knows them. Send this or customerId, not both.
valueintegerHow many units this event is worth, for rules whose trigger scales with it. Leave it out and the rule's own default applies. Rules that do not scale ignore it.
propertiesobjectFree-form facts about the event, as a flat object of strings, numbers and booleans, such as { "rating": 5, "channel": "store" }. Rules can require conditions on them.
idempotencyKeystringYour own identifier for this event, such as the id of the record that caused it. Sending it again for the same customer returns the event already recorded and awards nothing a second time. Leave it out and every call counts separately.
createCustomerbooleanCreate the customer when customerEmail is an address Meisei has never seen. Off by default, so a mistyped address is a 404 rather than a new record.
occurredAtstring (date-time)When the event happened, as an ISO 8601 timestamp. Defaults to now.
curl \
-X POST \
"https://your-store.meisei.app/api/loyalty-events" \
-H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "string",
"customerId": "string",
"customerEmail": "user@example.com",
"value": 0,
"properties": "...",
"idempotencyKey": "string",
"createCustomer": true,
"occurredAt": "2025-01-15T09:30:00Z"
}'import { client } from "@meisei/api/admin/client"
import { postLoyaltyEvents } from "@meisei/api/admin"
client.setConfig({
baseUrl: "https://your-store.meisei.app/api",
headers: { Authorization: "Bearer sk_YOUR_SECRET_KEY" },
})
const { data, error } = await postLoyaltyEvents({
body: {
name: "string",
customerId: "string",
customerEmail: "user@example.com",
value: 0,
properties: "...",
idempotencyKey: "string",
createCustomer: true,
occurredAt: "2025-01-15T09:30:00Z",
},
})require "meisei"
meisei = Meisei::Client.new(
secret_key: "sk_YOUR_SECRET_KEY",
base_url: "https://your-store.meisei.app/api",
)
result = meisei.loyalty_events.create(
name: "string",
customer_id: "string",
customer_email: "user@example.com",
value: 0,
properties: "...",
idempotency_key: "string",
create_customer: true,
occurred_at: "2025-01-15T09:30:00Z",
)from meisei import Client
meisei = Client(
secret_key="sk_YOUR_SECRET_KEY",
base_url="https://your-store.meisei.app/api",
)
result = meisei.loyalty_events.create(
name="string",
customer_id="string",
customer_email="user@example.com",
value=0,
properties={},
idempotency_key="string",
create_customer=True,
occurred_at="2025-01-15T09:30:00Z",
){
"event": {
"id": "A4Ws1igz",
"customerId": "A4Ws1igz",
"name": "string",
"value": 0,
"properties": "...",
"idempotencyKey": "string",
"occurredAt": "2025-01-15T09:30:00Z",
"createdAt": "2025-01-15T09:30:00Z"
},
"duplicate": true,
"loyaltyProgramIds": ["A4Ws1igz"],
"pausedLoyaltyProgramIds": ["A4Ws1igz"]
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"event": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the event.",
"idCodec": "sqid"
},
"customerId": {
"type": "string",
"description": "The customer the event is about.",
"idCodec": "sqid"
},
"name": {
"type": "string",
"description": "The event's name, such as `review.written`."
},
"value": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "How many units the event is worth, as sent. Null when it carried none."
},
"properties": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "string",
"maxLength": 500
},
{
"type": "number"
},
{
"type": "boolean"
}
]
},
"description": "Free-form facts about the event, as a flat object of strings, numbers and booleans, such as `{ \"rating\": 5, \"channel\": \"store\" }`. Rules can require conditions on them."
},
"idempotencyKey": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Your own identifier for the event, as sent. Null when it carried none."
},
"occurredAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the event happened."
},
"createdAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When Meisei recorded the event."
}
},
"required": [
"id",
"customerId",
"name",
"value",
"properties",
"idempotencyKey",
"occurredAt",
"createdAt"
],
"additionalProperties": false,
"description": "The recorded event."
},
"duplicate": {
"type": "boolean",
"description": "True when the idempotency key had already been used for this customer: the event is the one recorded the first time, and nothing was queued again."
},
"loyaltyProgramIds": {
"type": "array",
"items": {
"type": "string",
"description": "A loyalty program ID.",
"idCodec": "sqid"
},
"description": "The programs the event was queued for: those with a rule listening for its name."
},
"pausedLoyaltyProgramIds": {
"type": "array",
"items": {
"type": "string",
"description": "A loyalty program ID.",
"idCodec": "sqid"
},
"description": "Programs with a rule for the event that are paused. A paused program earns nothing, so the event was not queued for it."
}
},
"required": ["event", "duplicate", "loyaltyProgramIds", "pausedLoyaltyProgramIds"],
"additionalProperties": false
}GET /loyalty-events/{id}
Get a single custom event by ID.
Requires the loyalty:read permission.
Path parameters
idstringrequiredThe ID of the event.
Query parameters
includestringA comma-separated list of extra fields to compute and return. Each one costs an additional query, so ask only for what you need. Available: customer.
curl \
"https://your-store.meisei.app/api/loyalty-events/A4Ws1igz" \
-H "Authorization: Bearer sk_YOUR_SECRET_KEY"import { client } from "@meisei/api/admin/client"
import { getLoyaltyEventsById } from "@meisei/api/admin"
client.setConfig({
baseUrl: "https://your-store.meisei.app/api",
headers: { Authorization: "Bearer sk_YOUR_SECRET_KEY" },
})
const { data, error } = await getLoyaltyEventsById({
path: { id: "A4Ws1igz" },
})require "meisei"
meisei = Meisei::Client.new(
secret_key: "sk_YOUR_SECRET_KEY",
base_url: "https://your-store.meisei.app/api",
)
result = meisei.loyalty_events.retrieve("A4Ws1igz")from meisei import Client
meisei = Client(
secret_key="sk_YOUR_SECRET_KEY",
base_url="https://your-store.meisei.app/api",
)
result = meisei.loyalty_events.retrieve("A4Ws1igz"){
"id": "A4Ws1igz",
"customerId": "A4Ws1igz",
"name": "string",
"value": 0,
"properties": "...",
"idempotencyKey": "string",
"occurredAt": "2025-01-15T09:30:00Z",
"createdAt": "2025-01-15T09:30:00Z",
"customer": {
"id": "A4Ws1igz",
"email": "user@example.com",
"phone": "string",
"firstName": "string",
"lastName": "string",
"country": "string",
"metadata": "...",
"notes": "string",
"emailOptOut": true,
"emailOptOutAt": "2025-01-15T09:30:00Z",
"emailOptOutSource": "customer",
"createdAt": "2025-01-15T09:30:00Z",
"updatedAt": "2025-01-15T09:30:00Z"
}
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the event.",
"idCodec": "sqid"
},
"customerId": {
"type": "string",
"description": "The customer the event is about.",
"idCodec": "sqid"
},
"name": {
"type": "string",
"description": "The event's name, such as `review.written`."
},
"value": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "How many units the event is worth, as sent. Null when it carried none."
},
"properties": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "string",
"maxLength": 500
},
{
"type": "number"
},
{
"type": "boolean"
}
]
},
"description": "Free-form facts about the event, as a flat object of strings, numbers and booleans, such as `{ \"rating\": 5, \"channel\": \"store\" }`. Rules can require conditions on them."
},
"idempotencyKey": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Your own identifier for the event, as sent. Null when it carried none."
},
"occurredAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the event happened."
},
"createdAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When Meisei recorded the event."
},
"customer": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for the customer.",
"idCodec": "sqid"
},
"email": {
"type": "string",
"format": "email",
"pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
"description": "The customer's email address, unique within the organization."
},
"phone": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The customer's phone number in E.164 format."
},
"firstName": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The customer's first name."
},
"lastName": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The customer's last name."
},
"country": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "The customer's country, as an ISO 3166-1 code."
},
"metadata": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "boolean"
},
{
"type": "array",
"items": {
"type": "string"
}
}
],
"description": "A metadata value: a string, a number, true or false, or a list of strings. A key with a metadata definition holds the type its definition names."
},
"description": "Key/value pairs for your own data. Keys you define with `/metadata-definitions` are typed and validated; any other key is free-form. Individual keys are filterable with a dot path, for example `metadata.category`."
},
"notes": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"description": "Internal notes about the customer. Never shown to them."
},
"emailOptOut": {
"type": "boolean",
"description": "Whether the customer has opted out of marketing email. They still receive mail they asked for, such as a wishlist they shared themselves."
},
"emailOptOutAt": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
},
{
"type": "null"
}
],
"description": "When the opt-out was recorded. Null while the customer is still subscribed."
},
"emailOptOutSource": {
"anyOf": [
{
"type": "string",
"enum": ["customer", "merchant", "import", "shopify"],
"description": "Where the opt-out came from."
},
{
"type": "null"
}
],
"description": "Where the opt-out came from: `customer` (they opted out themselves, through an unsubscribe link or your integration), `merchant`, `import` or `shopify`. Null while the customer is still subscribed."
},
"createdAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the customer was first created in Meisei."
},
"updatedAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
"description": "When the customer was last changed."
}
},
"required": [
"id",
"email",
"phone",
"firstName",
"lastName",
"country",
"metadata",
"notes",
"emailOptOut",
"emailOptOutAt",
"emailOptOutSource",
"createdAt",
"updatedAt"
],
"additionalProperties": false,
"description": "The customer the event is about."
}
},
"required": [
"id",
"customerId",
"name",
"value",
"properties",
"idempotencyKey",
"occurredAt",
"createdAt"
],
"additionalProperties": false,
"description": "The requested event."
}