Automations

GET /automations

List the organization's automations, newest first by default.

Requires the automations:read permission.

Query parameters

limitnumber

The number of records to return.

cursorstring

A pagination cursor. Fetch the next page by passing the nextCursor value from the previous response.

sortname | -name | createdAt | -createdAt

The sort order. Prefix a field with - to sort descending. Defaults to -createdAt.

filterstring

A JSON-encoded filter document, for example {"createdAt":{"$gte":"2025-01-01T00:00:00Z"}}. Filterable fields: id, name, isActive, templateKey, createdAt. See Filtering for the syntax.

Request
curl \
  "https://your-store.meisei.app/api/automations" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "data": [
    {
      "id": "A4Ws1igz",
      "name": "string",
      "code": "string",
      "events": ["..."],
      "permissions": ["..."],
      "secretNames": ["..."],
      "isActive": true,
      "templateKey": "string",
      "parameters": ["..."],
      "config": "...",
      "emails": ["..."],
      "inbound": {
        "urlCreatedAt": "...",
        "signature": "...",
        "idempotencyHeader": "..."
      },
      "createdAt": "2025-01-15T09:30:00Z",
      "updatedAt": "2025-01-15T09:30:00Z"
    }
  ],
  "nextCursor": "string"
}

POST /automations

Create an automation: a script Meisei runs for you whenever one of its events happens, with an api client held to the permissions you give it. You can only give it permissions your own credential holds.

Requires the automations:write permission.

Body parameters

namestringrequired

What to call the automation.

codestringrequired

The script: a JavaScript module whose default export is async function (event, { meisei, secrets, config }). meisei calls the admin api as the automation (get, post, put, patch, delete), config holds the value of each parameter, and fetch reaches anywhere else. Imports are not supported.

eventscustomer.created | customer.updated | customer.deleted | order.created | order.updated | order.deleted | product.created | product.updated | product.deleted | productVariant.updated | review.created | review.updated | review.deleted | review.published | reviewQuestion.created | reviewQuestion.updated | reviewQuestion.deleted | site.created | site.updated | site.deleted | emailTemplate.created | emailTemplate.updated | emailTemplate.deleted | survey.deleted | reviewRequest.eligible | reviewRequest.canceled | loyaltyProgram.created | loyaltyProgram.updated | loyaltyProgram.deleted | loyaltyRule.created | loyaltyRule.updated | loyaltyRule.deleted | loyaltyTier.created | loyaltyTier.updated | loyaltyTier.deleted | loyaltyMembership.created | loyaltyMembership.updated | loyaltyMembership.deleted | loyaltyMembership.tierChanged | loyaltyMembership.pointsEarned | loyaltyTransaction.created | loyaltyReward.issued | loyaltyReward.claimed | loyaltyReward.redeemed | loyaltyReward.revoked | loyaltyReward.expired | loyaltyReward.expiringSoon | loyaltyPoints.expiringSoon | wishlist.created | wishlist.updated | wishlist.deleted | webhook.created | webhook.updated | webhook.deleted | metadataDefinition.created | metadataDefinition.updated | metadataDefinition.deleted | schedule.hourly | schedule.daily | inbound.received[]required

The events to run on. Call GET /webhook-events for the list; schedule.hourly and schedule.daily run on a clock, and inbound.received runs on a request to the automation's incoming URL.

permissionsanalytics:read | analytics:write | automations:read | automations:write | customers:read | customers:write | exports:read | exports:write | imports:read | imports:write | loyalty:read | loyalty:write | orders:read | orders:write | products:read | products:write | reviews:read | reviews:write | settings:read | settings:write | surveys:read | surveys:write | webhooks:read | webhooks:write | wishlists:read | wishlists:write[]

What the script's api calls may do, as on a secret key. You can only give permissions your own credential holds.

secretsobject

Values the script reads as secrets.NAME, such as another service's API key. They are never returned.

isActiveboolean

Whether the automation runs. Defaults to true.

parametersobject | object | object[]

The settings the automation asks for. Each has a key the script reads it under, a label, and a type of number (with optional min, max and integer), text, or select (with options). A default fills it in when config leaves it out.

configobject

A value for each parameter, by key. One left out takes the parameter's default, and a parameter with no default has to be given one.

emailsobject[]

The emails the automation owns, which its script sends with POST /customers/{id}/send-email. Each needs a key, a name, a subject and a body.

inboundobject

How the incoming URL checks a request. Fields left out are left alone. The URL itself is made with POST /automations/{id}/inbound-url.

templateKeyreview-requests | slack-review-alerts | review-edited | rating-badges | review-points | low-rating-follow-up | top-reviewer-tags | review-digest-slack | zendesk-review-tickets | loyalty-tiers | loyalty-emails | loyalty-tier-tags | birthday-events | scheduled-promotion | win-back | order-anniversary | order-streak | customer-segments | wishlist-alerts | wishlist-reminders-klaviyo | most-wished-tags | wishlist-demand-report | order-status-emails | custom-field-changes | shopify-review-metafields | shopify-customer-tags | shopify-most-wished-collection | woocommerce-orders | woocommerce-reward-coupons | null

The template this automation was started from, as GET /automation-templates names it.

Request
curl \
  -X POST \
  "https://your-store.meisei.app/api/automations" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "code": "string",
  "events": [
    "customer.created"
  ],
  "permissions": [],
  "secrets": "...",
  "isActive": true,
  "parameters": [
    {
      "key": "string",
      "label": "string",
      "description": "string",
      "type": "number",
      "default": 0,
      "min": 0,
      "max": 0,
      "integer": true
    }
  ],
  "config": "...",
  "emails": [
    {
      "key": "string",
      "name": "string",
      "subject": "string",
      "preheader": "string",
      "body": "string",
      "reason": "string",
      "sampleData": "..."
    }
  ],
  "inbound": {
    "signature": {
      "header": "string",
      "secretName": "string",
      "encoding": "hex",
      "prefix": ""
    },
    "idempotencyHeader": "string"
  },
  "templateKey": "review-requests"
}'
Response
{
  "id": "A4Ws1igz",
  "name": "string",
  "code": "string",
  "events": ["customer.created"],
  "permissions": ["analytics:read"],
  "secretNames": ["string"],
  "isActive": true,
  "templateKey": "string",
  "parameters": [
    {
      "key": "string",
      "label": "string",
      "description": "string",
      "type": "number",
      "default": 0,
      "min": 0,
      "max": 0,
      "integer": true
    }
  ],
  "config": "...",
  "emails": [
    {
      "key": "string",
      "name": "string",
      "subject": "string",
      "preheader": "string",
      "body": "string",
      "reason": "string",
      "sampleData": "..."
    }
  ],
  "inbound": {
    "urlCreatedAt": "2025-01-15T09:30:00Z",
    "signature": {
      "header": "string",
      "secretName": "string",
      "encoding": "hex",
      "prefix": "string"
    },
    "idempotencyHeader": "string"
  },
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z"
}

GET /automations/{id}

Get a single automation by ID, with its script. Secret values are never returned.

Requires the automations:read permission.

Path parameters

idstringrequired

The ID of the automation.

Request
curl \
  "https://your-store.meisei.app/api/automations/A4Ws1igz" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "id": "A4Ws1igz",
  "name": "string",
  "code": "string",
  "events": ["customer.created"],
  "permissions": ["analytics:read"],
  "secretNames": ["string"],
  "isActive": true,
  "templateKey": "string",
  "parameters": [
    {
      "key": "string",
      "label": "string",
      "description": "string",
      "type": "number",
      "default": 0,
      "min": 0,
      "max": 0,
      "integer": true
    }
  ],
  "config": "...",
  "emails": [
    {
      "key": "string",
      "name": "string",
      "subject": "string",
      "preheader": "string",
      "body": "string",
      "reason": "string",
      "sampleData": "..."
    }
  ],
  "inbound": {
    "urlCreatedAt": "2025-01-15T09:30:00Z",
    "signature": {
      "header": "string",
      "secretName": "string",
      "encoding": "hex",
      "prefix": "string"
    },
    "idempotencyHeader": "string"
  },
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z"
}

PUT /automations/{id}

Update an automation's name, script, events, permissions, secrets or active flag. Only the fields you send are changed, and the next run uses them. A change runs with the automation's permissions, so your credential has to hold every one of them; without them you can only set isActive to false.

Requires the automations:write permission.

Path parameters

idstringrequired

The ID of the automation.

Body parameters

namestring

A new name.

codestring

A new script. The next run uses it.

eventscustomer.created | customer.updated | customer.deleted | order.created | order.updated | order.deleted | product.created | product.updated | product.deleted | productVariant.updated | review.created | review.updated | review.deleted | review.published | reviewQuestion.created | reviewQuestion.updated | reviewQuestion.deleted | site.created | site.updated | site.deleted | emailTemplate.created | emailTemplate.updated | emailTemplate.deleted | survey.deleted | reviewRequest.eligible | reviewRequest.canceled | loyaltyProgram.created | loyaltyProgram.updated | loyaltyProgram.deleted | loyaltyRule.created | loyaltyRule.updated | loyaltyRule.deleted | loyaltyTier.created | loyaltyTier.updated | loyaltyTier.deleted | loyaltyMembership.created | loyaltyMembership.updated | loyaltyMembership.deleted | loyaltyMembership.tierChanged | loyaltyMembership.pointsEarned | loyaltyTransaction.created | loyaltyReward.issued | loyaltyReward.claimed | loyaltyReward.redeemed | loyaltyReward.revoked | loyaltyReward.expired | loyaltyReward.expiringSoon | loyaltyPoints.expiringSoon | wishlist.created | wishlist.updated | wishlist.deleted | webhook.created | webhook.updated | webhook.deleted | metadataDefinition.created | metadataDefinition.updated | metadataDefinition.deleted | schedule.hourly | schedule.daily | inbound.received[]

Replaces the list of events wholesale. Omit to leave it alone. Leaving out inbound.received turns the incoming URL off.

permissionsanalytics:read | analytics:write | automations:read | automations:write | customers:read | customers:write | exports:read | exports:write | imports:read | imports:write | loyalty:read | loyalty:write | orders:read | orders:write | products:read | products:write | reviews:read | reviews:write | settings:read | settings:write | surveys:read | surveys:write | webhooks:read | webhooks:write | wishlists:read | wishlists:write[]

Replaces the permissions wholesale. You can only give permissions your own credential holds.

secretsobject

Secrets to set or, with null, remove. A secret left out of the object is left alone.

isActiveboolean

Whether the automation runs.

parametersobject | object | object[]

Replaces the list of parameters wholesale. A value whose parameter is gone is dropped, and a new parameter takes its default.

configobject

Values to set or, with null, put back to the parameter's default. A parameter left out of the object keeps its value.

emailsobject[]

Replaces the emails wholesale. An email left out of the list is deleted.

inboundobject

How the incoming URL checks a request. Fields left out are left alone. The URL itself is made with POST /automations/{id}/inbound-url.

Request
curl \
  -X PUT \
  "https://your-store.meisei.app/api/automations/A4Ws1igz" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "code": "string",
  "events": [
    "customer.created"
  ],
  "permissions": [
    "analytics:read"
  ],
  "secrets": "...",
  "isActive": true,
  "parameters": [
    {
      "key": "string",
      "label": "string",
      "description": "string",
      "type": "number",
      "default": 0,
      "min": 0,
      "max": 0,
      "integer": true
    }
  ],
  "config": "...",
  "emails": [
    {
      "key": "string",
      "name": "string",
      "subject": "string",
      "preheader": "string",
      "body": "string",
      "reason": "string",
      "sampleData": "..."
    }
  ],
  "inbound": {
    "signature": {
      "header": "string",
      "secretName": "string",
      "encoding": "hex",
      "prefix": ""
    },
    "idempotencyHeader": "string"
  }
}'
Response
{
  "id": "A4Ws1igz",
  "name": "string",
  "code": "string",
  "events": ["customer.created"],
  "permissions": ["analytics:read"],
  "secretNames": ["string"],
  "isActive": true,
  "templateKey": "string",
  "parameters": [
    {
      "key": "string",
      "label": "string",
      "description": "string",
      "type": "number",
      "default": 0,
      "min": 0,
      "max": 0,
      "integer": true
    }
  ],
  "config": "...",
  "emails": [
    {
      "key": "string",
      "name": "string",
      "subject": "string",
      "preheader": "string",
      "body": "string",
      "reason": "string",
      "sampleData": "..."
    }
  ],
  "inbound": {
    "urlCreatedAt": "2025-01-15T09:30:00Z",
    "signature": {
      "header": "string",
      "secretName": "string",
      "encoding": "hex",
      "prefix": "string"
    },
    "idempotencyHeader": "string"
  },
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z"
}

DELETE /automations/{id}

Delete an automation and its run history. To pause it instead, set isActive to false.

Requires the automations:write permission.

Path parameters

idstringrequired

The ID of the automation.

Request
curl \
  -X DELETE \
  "https://your-store.meisei.app/api/automations/A4Ws1igz" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "id": "A4Ws1igz",
  "name": "string",
  "code": "string",
  "events": ["customer.created"],
  "permissions": ["analytics:read"],
  "secretNames": ["string"],
  "isActive": true,
  "templateKey": "string",
  "parameters": [
    {
      "key": "string",
      "label": "string",
      "description": "string",
      "type": "number",
      "default": 0,
      "min": 0,
      "max": 0,
      "integer": true
    }
  ],
  "config": "...",
  "emails": [
    {
      "key": "string",
      "name": "string",
      "subject": "string",
      "preheader": "string",
      "body": "string",
      "reason": "string",
      "sampleData": "..."
    }
  ],
  "inbound": {
    "urlCreatedAt": "2025-01-15T09:30:00Z",
    "signature": {
      "header": "string",
      "secretName": "string",
      "encoding": "hex",
      "prefix": "string"
    },
    "idempotencyHeader": "string"
  },
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z"
}

POST /automations/{id}/test

Run the script once, now, on an event you describe, whether or not the automation is active. The run is not retried, and its api calls are real, so a script that writes will write. Your credential has to hold every permission the automation holds. Poll the run for its logs and result.

Requires the automations:write permission.

Path parameters

idstringrequired

The ID of the automation.

Body parameters

eventNamecustomer.created | customer.updated | customer.deleted | order.created | order.updated | order.deleted | product.created | product.updated | product.deleted | productVariant.updated | review.created | review.updated | review.deleted | review.published | reviewQuestion.created | reviewQuestion.updated | reviewQuestion.deleted | site.created | site.updated | site.deleted | emailTemplate.created | emailTemplate.updated | emailTemplate.deleted | survey.deleted | reviewRequest.eligible | reviewRequest.canceled | loyaltyProgram.created | loyaltyProgram.updated | loyaltyProgram.deleted | loyaltyRule.created | loyaltyRule.updated | loyaltyRule.deleted | loyaltyTier.created | loyaltyTier.updated | loyaltyTier.deleted | loyaltyMembership.created | loyaltyMembership.updated | loyaltyMembership.deleted | loyaltyMembership.tierChanged | loyaltyMembership.pointsEarned | loyaltyTransaction.created | loyaltyReward.issued | loyaltyReward.claimed | loyaltyReward.redeemed | loyaltyReward.revoked | loyaltyReward.expired | loyaltyReward.expiringSoon | loyaltyPoints.expiringSoon | wishlist.created | wishlist.updated | wishlist.deleted | webhook.created | webhook.updated | webhook.deleted | metadataDefinition.created | metadataDefinition.updated | metadataDefinition.deleted | schedule.hourly | schedule.daily | inbound.receivedrequired

The event to pretend happened.

dataunknown

The event's data, as a delivery would carry it. Leave it out to reuse the latest real event of that name (for inbound.received, the latest request to this automation's URL), or null when there has not been one.

Request
curl \
  -X POST \
  "https://your-store.meisei.app/api/automations/A4Ws1igz/test" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "eventName": "customer.created",
  "data": "..."
}'
Response
{
  "id": "A4Ws1igz",
  "automationId": "A4Ws1igz",
  "eventName": "customer.created",
  "idempotencyKey": "string",
  "event": "...",
  "isTest": true,
  "status": "pending",
  "attempts": 0,
  "nextAttemptAt": "2025-01-15T09:30:00Z",
  "logs": [
    {
      "level": "log",
      "message": "string",
      "at": "2025-01-15T09:30:00Z"
    }
  ],
  "returnValue": "...",
  "error": "string",
  "durationMs": 0,
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z"
}

POST /automations/{id}/inbound-url

Make the automation's incoming URL: an address another app can post to, such as a WooCommerce or Stripe webhook, where each request runs the script with the request as its event. The automation has to run on inbound.received. The URL is returned once, here, and making a new one turns the old one off. Your credential has to hold every permission the automation holds.

Requires the automations:write permission.

Path parameters

idstringrequired

The ID of the automation.

Request
curl \
  -X POST \
  "https://your-store.meisei.app/api/automations/A4Ws1igz/inbound-url" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "url": "string",
  "token": "string",
  "createdAt": "2025-01-15T09:30:00Z"
}

DELETE /automations/{id}/inbound-url

Turn the automation's incoming URL off. A request to it is answered with a 404 from then on.

Requires the automations:write permission.

Path parameters

idstringrequired

The ID of the automation.

Request
curl \
  -X DELETE \
  "https://your-store.meisei.app/api/automations/A4Ws1igz/inbound-url" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "id": "A4Ws1igz",
  "name": "string",
  "code": "string",
  "events": ["customer.created"],
  "permissions": ["analytics:read"],
  "secretNames": ["string"],
  "isActive": true,
  "templateKey": "string",
  "parameters": [
    {
      "key": "string",
      "label": "string",
      "description": "string",
      "type": "number",
      "default": 0,
      "min": 0,
      "max": 0,
      "integer": true
    }
  ],
  "config": "...",
  "emails": [
    {
      "key": "string",
      "name": "string",
      "subject": "string",
      "preheader": "string",
      "body": "string",
      "reason": "string",
      "sampleData": "..."
    }
  ],
  "inbound": {
    "urlCreatedAt": "2025-01-15T09:30:00Z",
    "signature": {
      "header": "string",
      "secretName": "string",
      "encoding": "hex",
      "prefix": "string"
    },
    "idempotencyHeader": "string"
  },
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z"
}

GET /automations/{id}/runs

List an automation's recent runs, newest first, with what each one logged, returned or threw. Pass status=failed to find the runs that ran out of retries.

Requires the automations:read permission.

Path parameters

idstringrequired

The ID of the automation.

Query parameters

limitnumber

The number of runs to return.

statuspending | retrying | succeeded | failed

Only return runs in this state.

Request
curl \
  "https://your-store.meisei.app/api/automations/A4Ws1igz/runs" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "data": [
    {
      "id": "A4Ws1igz",
      "automationId": "A4Ws1igz",
      "eventName": "customer.created",
      "idempotencyKey": "string",
      "event": "...",
      "isTest": true,
      "status": "pending",
      "attempts": 0,
      "nextAttemptAt": "2025-01-15T09:30:00Z",
      "logs": ["..."],
      "returnValue": "...",
      "error": "string",
      "durationMs": 0,
      "createdAt": "2025-01-15T09:30:00Z",
      "updatedAt": "2025-01-15T09:30:00Z"
    }
  ],
  "nextCursor": "string"
}

GET /automations/{id}/runs/{runId}

Get a single run, with its logs, return value and any error.

Requires the automations:read permission.

Path parameters

idstringrequired

The ID of the automation.

runIdstringrequired

The ID of the run.

Request
curl \
  "https://your-store.meisei.app/api/automations/A4Ws1igz/runs/A4Ws1igz" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "id": "A4Ws1igz",
  "automationId": "A4Ws1igz",
  "eventName": "customer.created",
  "idempotencyKey": "string",
  "event": "...",
  "isTest": true,
  "status": "pending",
  "attempts": 0,
  "nextAttemptAt": "2025-01-15T09:30:00Z",
  "logs": [
    {
      "level": "log",
      "message": "string",
      "at": "2025-01-15T09:30:00Z"
    }
  ],
  "returnValue": "...",
  "error": "string",
  "durationMs": 0,
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z"
}

POST /automations/{id}/runs/{runId}/rerun

Run the script again for the same event, now, with the automation's current script. It is one attempt and is not retried on its own if it fails. Use it after fixing a script that failed. Your credential has to hold every permission the automation holds.

Requires the automations:write permission.

Path parameters

idstringrequired

The ID of the automation.

runIdstringrequired

The ID of the run.

Request
curl \
  -X POST \
  "https://your-store.meisei.app/api/automations/A4Ws1igz/runs/A4Ws1igz/rerun" \
  -H "Authorization: Bearer sk_YOUR_SECRET_KEY"
Response
{
  "id": "A4Ws1igz",
  "automationId": "A4Ws1igz",
  "eventName": "customer.created",
  "idempotencyKey": "string",
  "event": "...",
  "isTest": true,
  "status": "pending",
  "attempts": 0,
  "nextAttemptAt": "2025-01-15T09:30:00Z",
  "logs": [
    {
      "level": "log",
      "message": "string",
      "at": "2025-01-15T09:30:00Z"
    }
  ],
  "returnValue": "...",
  "error": "string",
  "durationMs": 0,
  "createdAt": "2025-01-15T09:30:00Z",
  "updatedAt": "2025-01-15T09:30:00Z"
}