Skip to main content
Documentation

Automations

automations.get

Read one automation step by step — what it sends, and when
Read-onlyRead budget

REST

Shipping
POST /api/v1/automations/get

MCP tool

Live
automations.get

Exposed on: REST API · Shop MCP server · Claude connector · Dash (in-app copilot) · Zapier. Part of the Automations domain.

Operating contract

WHAT THIS RULE ACTUALLY DOES, in order: every step, the waits between them, and the words that go out. automations.list says a rule has five steps; this says what those five steps do to a customer.

READ THIS BEFORE ANSWERING ANYTHING ABOUT WHAT A CUSTOMER WAS SENT. A rule's NAME is what somebody typed in a box, and it is routinely wrong about the rule's behaviour — 'Booking reminder' has sent a review request more than once.

customer_facing: true MARKS THE STEPS A REAL PERSON RECEIVES. Those are the ones that clear the compliance rails, and they are the only ones worth reading out when somebody asks what a customer got. A rule made entirely of tags and notes reaches nobody at all — which is a real and frequently surprising finding.

summary IS THE PRODUCT'S OWN DESCRIPTION of the step, including a snippet of the text a customer receives. Quote it rather than paraphrasing a step kind.

TIMING IS IN THE STEPS THEMSELVES. A wait step is a delay in the middle of a sequence, and wait_for_business_hours holds the rest of the rule until the shop is open — which is why a text somebody expected at eight in the evening arrives the next morning and looks like a failure.

stop_if ENDS THE RUN when its conditions match, so every step after it is conditional. A sequence read as though it always completes is a sequence read wrong.

enabled: false on the rule, or the shop's master switch off, means NONE of this runs however good it looks. Both are on the response.

One rule and all of its steps, entirely returned, so nothing is truncated. Editing a rule is a person in the builder: these words are sent to real customers over the shop's own number.

Who may call it

Permission
shop.manageThe caller must hold shop.manage at the ACT level. A read-only dashboard grant on the same section is refused.
Plan
Every planNo plan gate. Available on every Service VIN plan.
Retries
naturalNaturally idempotent — running it twice leaves the same world as running it once. A retrying integration needs no key.
Rate class
readCounted against the read budget — the widest of the four.

Input

FieldTypeDescription
automation_idrequiredstringuuid

The rule to read, as returned by automations.list.

Output

FieldTypeDescription
idstring

namestring

descriptionstring | null

trigger_typestring

enabledboolean

master_enabledboolean

cooldown_daysnumber

run_countnumber

last_run_atstring | null

reaches_customerboolean

stepsobject[]

steps[].positionnumber

steps[].kindstring

steps[].labelstring

steps[].groupstring

steps[].customer_facingboolean

steps[].summarystring

unreadable_stepsnumber

Examples

Built from this capability's own schema — required fields and the ones carrying a default, and nothing invented. Paste one and it validates.

curl
export SERVICEVIN_API_KEY=svk_live_…

curl -X POST https://www.servicevin.com/api/v1/automations/get \
  -H "Authorization: Bearer $SERVICEVIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"automation_id":"9b2f1c6e-4a77-4d2b-9f31-0f1c9a8e5d20"}'

TypeScript (fetch)
const res = await fetch("https://www.servicevin.com/api/v1/automations/get", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SERVICEVIN_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "automation_id": "9b2f1c6e-4a77-4d2b-9f31-0f1c9a8e5d20"
  }),
});

// Success and failure are both envelopes. Switch on error.code, never
// on error.message — the codes are stable, the messages are for people.
const payload = await res.json();
if (!res.ok) throw new Error(payload.error.code);
const data = payload.data;

Python (requests)
import os, requests

res = requests.post(
    "https://www.servicevin.com/api/v1/automations/get",
    headers={"Authorization": f"Bearer {os.environ['SERVICEVIN_API_KEY']}"},
    json={
    "automation_id": "9b2f1c6e-4a77-4d2b-9f31-0f1c9a8e5d20"
},
    timeout=30,
)
payload = res.json()
if not res.ok:
    raise RuntimeError(payload["error"]["code"])
data = payload["data"]

MCP tools/call — https://www.servicevin.com/api/mcp
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "automations.get",
    "arguments": {
      "automation_id": "9b2f1c6e-4a77-4d2b-9f31-0f1c9a8e5d20"
    }
  }
}

Refusals

The four gates run in this order on every surface, and the order is not arbitrary — see Authentication.

StatusCodeWhen
404not_foundThe id is unknown, or the feature is not enabled for this account. Deliberately the same answer for both.
403forbiddenThis login does not hold shop.manage.
422validation_errorAn argument was wrong. The message names the field.
429rate_limitedToo many read calls. Back off and retry.
500internal_errorSomething failed on our side. Nothing was changed.