@clawpify/skills 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +73 -0
- package/clawpify/SKILL.md +134 -0
- package/clawpify/references/blogs.md +385 -0
- package/clawpify/references/bulk-operations.md +386 -0
- package/clawpify/references/collections.md +71 -0
- package/clawpify/references/customers.md +141 -0
- package/clawpify/references/discounts.md +431 -0
- package/clawpify/references/draft-orders.md +495 -0
- package/clawpify/references/files.md +355 -0
- package/clawpify/references/fulfillments.md +437 -0
- package/clawpify/references/gift-cards.md +453 -0
- package/clawpify/references/inventory.md +107 -0
- package/clawpify/references/locations.md +349 -0
- package/clawpify/references/marketing.md +352 -0
- package/clawpify/references/markets.md +346 -0
- package/clawpify/references/menus.md +313 -0
- package/clawpify/references/metafields.md +461 -0
- package/clawpify/references/orders.md +164 -0
- package/clawpify/references/pages.md +308 -0
- package/clawpify/references/products.md +277 -0
- package/clawpify/references/refunds.md +401 -0
- package/clawpify/references/segments.md +319 -0
- package/clawpify/references/shipping.md +406 -0
- package/clawpify/references/shop.md +307 -0
- package/clawpify/references/subscriptions.md +429 -0
- package/clawpify/references/translations.md +270 -0
- package/clawpify/references/webhooks.md +400 -0
- package/dist/agent.d.ts +18 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +100 -0
- package/dist/auth.d.ts +34 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +58 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/mcp-server.d.ts +3 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +236 -0
- package/dist/shopify.d.ts +29 -0
- package/dist/shopify.d.ts.map +1 -0
- package/dist/shopify.js +41 -0
- package/dist/skills.d.ts +8 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +36 -0
- package/package.json +100 -0
- package/src/agent.ts +133 -0
- package/src/auth.ts +109 -0
- package/src/index.ts +55 -0
- package/src/mcp-server.ts +190 -0
- package/src/shopify.ts +63 -0
- package/src/skills.ts +42 -0
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# Shopify Locations
|
|
2
|
+
|
|
3
|
+
Manage inventory locations for fulfillment via the GraphQL Admin API.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
Locations are physical places where you stock inventory and fulfill orders from. Each location can have different inventory levels and fulfillment settings.
|
|
8
|
+
|
|
9
|
+
## List Locations
|
|
10
|
+
|
|
11
|
+
```graphql
|
|
12
|
+
query ListLocations($first: Int!, $includeInactive: Boolean) {
|
|
13
|
+
locations(first: $first, includeInactive: $includeInactive) {
|
|
14
|
+
nodes {
|
|
15
|
+
id
|
|
16
|
+
name
|
|
17
|
+
isActive
|
|
18
|
+
fulfillsOnlineOrders
|
|
19
|
+
address {
|
|
20
|
+
address1
|
|
21
|
+
address2
|
|
22
|
+
city
|
|
23
|
+
province
|
|
24
|
+
country
|
|
25
|
+
zip
|
|
26
|
+
phone
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
Variables: `{ "first": 20, "includeInactive": false }`
|
|
33
|
+
|
|
34
|
+
## Get Location
|
|
35
|
+
|
|
36
|
+
```graphql
|
|
37
|
+
query GetLocation($id: ID!) {
|
|
38
|
+
location(id: $id) {
|
|
39
|
+
id
|
|
40
|
+
name
|
|
41
|
+
isActive
|
|
42
|
+
isPrimary
|
|
43
|
+
fulfillsOnlineOrders
|
|
44
|
+
hasActiveInventory
|
|
45
|
+
shipsInventory
|
|
46
|
+
address {
|
|
47
|
+
address1
|
|
48
|
+
address2
|
|
49
|
+
city
|
|
50
|
+
province
|
|
51
|
+
provinceCode
|
|
52
|
+
country
|
|
53
|
+
countryCode
|
|
54
|
+
zip
|
|
55
|
+
phone
|
|
56
|
+
}
|
|
57
|
+
localPickupSettingsV2 {
|
|
58
|
+
instructions
|
|
59
|
+
pickupTime
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
Variables: `{ "id": "gid://shopify/Location/123" }`
|
|
65
|
+
|
|
66
|
+
## Get Locations Count
|
|
67
|
+
|
|
68
|
+
```graphql
|
|
69
|
+
query GetLocationsCount {
|
|
70
|
+
locationsCount {
|
|
71
|
+
count
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Add Location
|
|
77
|
+
|
|
78
|
+
```graphql
|
|
79
|
+
mutation AddLocation($input: LocationAddInput!) {
|
|
80
|
+
locationAdd(input: $input) {
|
|
81
|
+
location {
|
|
82
|
+
id
|
|
83
|
+
name
|
|
84
|
+
address {
|
|
85
|
+
address1
|
|
86
|
+
city
|
|
87
|
+
country
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
userErrors {
|
|
91
|
+
field
|
|
92
|
+
message
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
Variables:
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"input": {
|
|
101
|
+
"name": "New York Warehouse",
|
|
102
|
+
"address": {
|
|
103
|
+
"address1": "123 Warehouse Ave",
|
|
104
|
+
"city": "New York",
|
|
105
|
+
"provinceCode": "NY",
|
|
106
|
+
"countryCode": "US",
|
|
107
|
+
"zip": "10001",
|
|
108
|
+
"phone": "+1-212-555-0100"
|
|
109
|
+
},
|
|
110
|
+
"fulfillsOnlineOrders": true
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Edit Location
|
|
116
|
+
|
|
117
|
+
```graphql
|
|
118
|
+
mutation EditLocation($id: ID!, $input: LocationEditInput!) {
|
|
119
|
+
locationEdit(id: $id, input: $input) {
|
|
120
|
+
location {
|
|
121
|
+
id
|
|
122
|
+
name
|
|
123
|
+
address {
|
|
124
|
+
address1
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
userErrors {
|
|
128
|
+
field
|
|
129
|
+
message
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
Variables:
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"id": "gid://shopify/Location/123",
|
|
138
|
+
"input": {
|
|
139
|
+
"name": "NY Warehouse - Main",
|
|
140
|
+
"address": {
|
|
141
|
+
"phone": "+1-212-555-0200"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Activate Location
|
|
148
|
+
|
|
149
|
+
```graphql
|
|
150
|
+
mutation ActivateLocation($locationId: ID!) {
|
|
151
|
+
locationActivate(locationId: $locationId) {
|
|
152
|
+
location {
|
|
153
|
+
id
|
|
154
|
+
isActive
|
|
155
|
+
}
|
|
156
|
+
userErrors {
|
|
157
|
+
field
|
|
158
|
+
message
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Deactivate Location
|
|
165
|
+
|
|
166
|
+
```graphql
|
|
167
|
+
mutation DeactivateLocation($locationId: ID!, $destinationLocationId: ID) {
|
|
168
|
+
locationDeactivate(locationId: $locationId, destinationLocationId: $destinationLocationId) {
|
|
169
|
+
location {
|
|
170
|
+
id
|
|
171
|
+
isActive
|
|
172
|
+
}
|
|
173
|
+
userErrors {
|
|
174
|
+
field
|
|
175
|
+
message
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Note: When deactivating, inventory moves to the destination location.
|
|
182
|
+
|
|
183
|
+
## Delete Location
|
|
184
|
+
|
|
185
|
+
```graphql
|
|
186
|
+
mutation DeleteLocation($locationId: ID!) {
|
|
187
|
+
locationDelete(locationId: $locationId) {
|
|
188
|
+
deletedLocationId
|
|
189
|
+
userErrors {
|
|
190
|
+
field
|
|
191
|
+
message
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Enable Local Pickup
|
|
198
|
+
|
|
199
|
+
```graphql
|
|
200
|
+
mutation EnableLocalPickup($localPickupSettings: DeliveryLocationLocalPickupEnableInput!) {
|
|
201
|
+
locationLocalPickupEnable(localPickupSettings: $localPickupSettings) {
|
|
202
|
+
userErrors {
|
|
203
|
+
field
|
|
204
|
+
message
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
Variables:
|
|
210
|
+
```json
|
|
211
|
+
{
|
|
212
|
+
"localPickupSettings": {
|
|
213
|
+
"locationId": "gid://shopify/Location/123",
|
|
214
|
+
"instructions": "Located at the back of the store. Ring the bell for assistance.",
|
|
215
|
+
"pickupTime": "TWENTY_FOUR_HOURS"
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Disable Local Pickup
|
|
221
|
+
|
|
222
|
+
```graphql
|
|
223
|
+
mutation DisableLocalPickup($locationId: ID!) {
|
|
224
|
+
locationLocalPickupDisable(locationId: $locationId) {
|
|
225
|
+
userErrors {
|
|
226
|
+
field
|
|
227
|
+
message
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Location by Identifier
|
|
234
|
+
|
|
235
|
+
```graphql
|
|
236
|
+
query GetLocationByIdentifier($identifier: LocationIdentifierInput!) {
|
|
237
|
+
locationByIdentifier(identifier: $identifier) {
|
|
238
|
+
id
|
|
239
|
+
name
|
|
240
|
+
isActive
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
Variables:
|
|
245
|
+
```json
|
|
246
|
+
{
|
|
247
|
+
"identifier": {
|
|
248
|
+
"gid": "gid://shopify/Location/123"
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Locations for Delivery Profiles
|
|
254
|
+
|
|
255
|
+
```graphql
|
|
256
|
+
query GetDeliveryLocations($first: Int!) {
|
|
257
|
+
locationsAvailableForDeliveryProfilesConnection(first: $first) {
|
|
258
|
+
nodes {
|
|
259
|
+
id
|
|
260
|
+
name
|
|
261
|
+
fulfillsOnlineOrders
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Location Fields
|
|
268
|
+
|
|
269
|
+
| Field | Description |
|
|
270
|
+
|-------|-------------|
|
|
271
|
+
| `name` | Display name |
|
|
272
|
+
| `isActive` | Whether location is active |
|
|
273
|
+
| `isPrimary` | Default location for inventory |
|
|
274
|
+
| `fulfillsOnlineOrders` | Can fulfill online orders |
|
|
275
|
+
| `hasActiveInventory` | Has inventory tracked here |
|
|
276
|
+
| `shipsInventory` | Can ship from this location |
|
|
277
|
+
| `activatable` | Can be activated |
|
|
278
|
+
| `deactivatable` | Can be deactivated |
|
|
279
|
+
| `deletable` | Can be deleted |
|
|
280
|
+
|
|
281
|
+
## Local Pickup Times
|
|
282
|
+
|
|
283
|
+
| Value | Description |
|
|
284
|
+
|-------|-------------|
|
|
285
|
+
| `ONE_HOUR` | Ready in 1 hour |
|
|
286
|
+
| `TWO_HOURS` | Ready in 2 hours |
|
|
287
|
+
| `FOUR_HOURS` | Ready in 4 hours |
|
|
288
|
+
| `TWENTY_FOUR_HOURS` | Ready in 24 hours |
|
|
289
|
+
| `TWO_TO_FOUR_DAYS` | Ready in 2-4 days |
|
|
290
|
+
| `FIVE_OR_MORE_DAYS` | Ready in 5+ days |
|
|
291
|
+
|
|
292
|
+
## B2B Company Locations
|
|
293
|
+
|
|
294
|
+
For B2B businesses:
|
|
295
|
+
|
|
296
|
+
```graphql
|
|
297
|
+
query ListCompanyLocations($first: Int!) {
|
|
298
|
+
companyLocations(first: $first) {
|
|
299
|
+
nodes {
|
|
300
|
+
id
|
|
301
|
+
name
|
|
302
|
+
company {
|
|
303
|
+
id
|
|
304
|
+
name
|
|
305
|
+
}
|
|
306
|
+
billingAddress {
|
|
307
|
+
address1
|
|
308
|
+
city
|
|
309
|
+
}
|
|
310
|
+
shippingAddress {
|
|
311
|
+
address1
|
|
312
|
+
city
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
### Create Company Location
|
|
320
|
+
|
|
321
|
+
```graphql
|
|
322
|
+
mutation CreateCompanyLocation($companyId: ID!, $input: CompanyLocationInput!) {
|
|
323
|
+
companyLocationCreate(companyId: $companyId, input: $input) {
|
|
324
|
+
companyLocation {
|
|
325
|
+
id
|
|
326
|
+
name
|
|
327
|
+
}
|
|
328
|
+
userErrors {
|
|
329
|
+
field
|
|
330
|
+
message
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
## API Scopes Required
|
|
337
|
+
|
|
338
|
+
- `read_locations` - Read locations
|
|
339
|
+
- `write_locations` - Create, update, delete locations
|
|
340
|
+
- `read_inventory` - Read inventory at locations
|
|
341
|
+
- `write_inventory` - Manage inventory at locations
|
|
342
|
+
|
|
343
|
+
## Notes
|
|
344
|
+
|
|
345
|
+
- At least one location must remain active
|
|
346
|
+
- Deactivating transfers inventory to another location
|
|
347
|
+
- Primary location is the default for new inventory
|
|
348
|
+
- Location changes affect fulfillment order assignments
|
|
349
|
+
- Local pickup requires location address to be complete
|
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
# Shopify Marketing
|
|
2
|
+
|
|
3
|
+
Manage marketing activities, events, and customer marketing consent via the GraphQL Admin API.
|
|
4
|
+
|
|
5
|
+
## Marketing Activities
|
|
6
|
+
|
|
7
|
+
Marketing activities track promotional campaigns like email marketing, social media ads, and other marketing efforts.
|
|
8
|
+
|
|
9
|
+
### List Marketing Activities
|
|
10
|
+
|
|
11
|
+
```graphql
|
|
12
|
+
query ListMarketingActivities($first: Int!, $after: String) {
|
|
13
|
+
marketingActivities(first: $first, after: $after, sortKey: CREATED_AT, reverse: true) {
|
|
14
|
+
pageInfo {
|
|
15
|
+
hasNextPage
|
|
16
|
+
endCursor
|
|
17
|
+
}
|
|
18
|
+
nodes {
|
|
19
|
+
id
|
|
20
|
+
title
|
|
21
|
+
activityListUrl
|
|
22
|
+
status
|
|
23
|
+
createdAt
|
|
24
|
+
budget {
|
|
25
|
+
budgetType
|
|
26
|
+
total {
|
|
27
|
+
amount
|
|
28
|
+
currencyCode
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
utmParameters {
|
|
32
|
+
campaign
|
|
33
|
+
source
|
|
34
|
+
medium
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
Variables: `{ "first": 10 }`
|
|
41
|
+
|
|
42
|
+
### Get Marketing Activity
|
|
43
|
+
|
|
44
|
+
```graphql
|
|
45
|
+
query GetMarketingActivity($id: ID!) {
|
|
46
|
+
marketingActivity(id: $id) {
|
|
47
|
+
id
|
|
48
|
+
title
|
|
49
|
+
status
|
|
50
|
+
activityListUrl
|
|
51
|
+
createdAt
|
|
52
|
+
budget {
|
|
53
|
+
budgetType
|
|
54
|
+
total {
|
|
55
|
+
amount
|
|
56
|
+
currencyCode
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
utmParameters {
|
|
60
|
+
campaign
|
|
61
|
+
source
|
|
62
|
+
medium
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
Variables: `{ "id": "gid://shopify/MarketingActivity/123" }`
|
|
68
|
+
|
|
69
|
+
### Create External Marketing Activity
|
|
70
|
+
|
|
71
|
+
```graphql
|
|
72
|
+
mutation CreateExternalMarketingActivity($input: MarketingActivityCreateExternalInput!) {
|
|
73
|
+
marketingActivityCreateExternal(input: $input) {
|
|
74
|
+
marketingActivity {
|
|
75
|
+
id
|
|
76
|
+
title
|
|
77
|
+
status
|
|
78
|
+
}
|
|
79
|
+
userErrors {
|
|
80
|
+
field
|
|
81
|
+
message
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
Variables:
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"input": {
|
|
90
|
+
"title": "Summer Email Campaign",
|
|
91
|
+
"remoteId": "campaign-123",
|
|
92
|
+
"utm": {
|
|
93
|
+
"campaign": "summer_sale",
|
|
94
|
+
"source": "email",
|
|
95
|
+
"medium": "newsletter"
|
|
96
|
+
},
|
|
97
|
+
"budget": {
|
|
98
|
+
"budgetType": "DAILY",
|
|
99
|
+
"total": {
|
|
100
|
+
"amount": "100.00",
|
|
101
|
+
"currencyCode": "USD"
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
"scheduledToEndAt": "2025-08-31T23:59:59Z",
|
|
105
|
+
"adSpend": {
|
|
106
|
+
"amount": "0.00",
|
|
107
|
+
"currencyCode": "USD"
|
|
108
|
+
},
|
|
109
|
+
"channelHandle": "email-marketing"
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Update External Marketing Activity
|
|
115
|
+
|
|
116
|
+
```graphql
|
|
117
|
+
mutation UpdateExternalMarketingActivity($marketingActivityId: ID!, $input: MarketingActivityUpdateExternalInput!) {
|
|
118
|
+
marketingActivityUpdateExternal(marketingActivityId: $marketingActivityId, input: $input) {
|
|
119
|
+
marketingActivity {
|
|
120
|
+
id
|
|
121
|
+
title
|
|
122
|
+
status
|
|
123
|
+
}
|
|
124
|
+
userErrors {
|
|
125
|
+
field
|
|
126
|
+
message
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Delete External Marketing Activity
|
|
133
|
+
|
|
134
|
+
```graphql
|
|
135
|
+
mutation DeleteExternalMarketingActivity($marketingActivityId: ID!) {
|
|
136
|
+
marketingActivityDeleteExternal(marketingActivityId: $marketingActivityId) {
|
|
137
|
+
deletedMarketingActivityId
|
|
138
|
+
userErrors {
|
|
139
|
+
field
|
|
140
|
+
message
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Marketing Events
|
|
147
|
+
|
|
148
|
+
Marketing events represent trackable marketing-related actions.
|
|
149
|
+
|
|
150
|
+
### List Marketing Events
|
|
151
|
+
|
|
152
|
+
```graphql
|
|
153
|
+
query ListMarketingEvents($first: Int!) {
|
|
154
|
+
marketingEvents(first: $first, sortKey: STARTED_AT, reverse: true) {
|
|
155
|
+
nodes {
|
|
156
|
+
id
|
|
157
|
+
type
|
|
158
|
+
startedAt
|
|
159
|
+
channel
|
|
160
|
+
utmParameters {
|
|
161
|
+
campaign
|
|
162
|
+
source
|
|
163
|
+
medium
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Get Marketing Event
|
|
171
|
+
|
|
172
|
+
```graphql
|
|
173
|
+
query GetMarketingEvent($id: ID!) {
|
|
174
|
+
marketingEvent(id: $id) {
|
|
175
|
+
id
|
|
176
|
+
type
|
|
177
|
+
startedAt
|
|
178
|
+
endedAt
|
|
179
|
+
channel
|
|
180
|
+
utmParameters {
|
|
181
|
+
campaign
|
|
182
|
+
source
|
|
183
|
+
medium
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Marketing Engagement
|
|
190
|
+
|
|
191
|
+
Track engagement metrics for marketing activities.
|
|
192
|
+
|
|
193
|
+
### Create Marketing Engagement
|
|
194
|
+
|
|
195
|
+
```graphql
|
|
196
|
+
mutation CreateMarketingEngagement($marketingActivityId: ID!, $marketingEngagement: MarketingEngagementInput!) {
|
|
197
|
+
marketingEngagementCreate(marketingActivityId: $marketingActivityId, marketingEngagement: $marketingEngagement) {
|
|
198
|
+
marketingEngagement {
|
|
199
|
+
occurredOn
|
|
200
|
+
impressionsCount
|
|
201
|
+
clicksCount
|
|
202
|
+
sessionsCount
|
|
203
|
+
salesAmount {
|
|
204
|
+
amount
|
|
205
|
+
currencyCode
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
userErrors {
|
|
209
|
+
field
|
|
210
|
+
message
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
Variables:
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"marketingActivityId": "gid://shopify/MarketingActivity/123",
|
|
219
|
+
"marketingEngagement": {
|
|
220
|
+
"occurredOn": "2025-01-15",
|
|
221
|
+
"impressionsCount": 5000,
|
|
222
|
+
"clicksCount": 150,
|
|
223
|
+
"sessionsCount": 120,
|
|
224
|
+
"ordersCount": 10,
|
|
225
|
+
"salesAmount": {
|
|
226
|
+
"amount": "1500.00",
|
|
227
|
+
"currencyCode": "USD"
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Delete Marketing Engagements
|
|
234
|
+
|
|
235
|
+
```graphql
|
|
236
|
+
mutation DeleteMarketingEngagements($channelHandle: String!) {
|
|
237
|
+
marketingEngagementsDelete(channelHandle: $channelHandle) {
|
|
238
|
+
deletedMarketingEngagementsCount
|
|
239
|
+
userErrors {
|
|
240
|
+
field
|
|
241
|
+
message
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Customer Marketing Consent
|
|
248
|
+
|
|
249
|
+
### Update Email Marketing Consent
|
|
250
|
+
|
|
251
|
+
```graphql
|
|
252
|
+
mutation UpdateEmailMarketingConsent($input: CustomerEmailMarketingConsentUpdateInput!) {
|
|
253
|
+
customerEmailMarketingConsentUpdate(input: $input) {
|
|
254
|
+
customer {
|
|
255
|
+
id
|
|
256
|
+
defaultEmailAddress {
|
|
257
|
+
emailAddress
|
|
258
|
+
marketingState
|
|
259
|
+
marketingOptInLevel
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
userErrors {
|
|
263
|
+
field
|
|
264
|
+
message
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
Variables:
|
|
270
|
+
```json
|
|
271
|
+
{
|
|
272
|
+
"input": {
|
|
273
|
+
"customerId": "gid://shopify/Customer/123",
|
|
274
|
+
"emailMarketingConsent": {
|
|
275
|
+
"marketingState": "SUBSCRIBED",
|
|
276
|
+
"marketingOptInLevel": "SINGLE_OPT_IN",
|
|
277
|
+
"consentUpdatedAt": "2025-01-15T10:00:00Z"
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Update SMS Marketing Consent
|
|
284
|
+
|
|
285
|
+
```graphql
|
|
286
|
+
mutation UpdateSmsMarketingConsent($input: CustomerSmsMarketingConsentUpdateInput!) {
|
|
287
|
+
customerSmsMarketingConsentUpdate(input: $input) {
|
|
288
|
+
customer {
|
|
289
|
+
id
|
|
290
|
+
smsMarketingConsent {
|
|
291
|
+
marketingState
|
|
292
|
+
marketingOptInLevel
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
userErrors {
|
|
296
|
+
field
|
|
297
|
+
message
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
Variables:
|
|
303
|
+
```json
|
|
304
|
+
{
|
|
305
|
+
"input": {
|
|
306
|
+
"customerId": "gid://shopify/Customer/123",
|
|
307
|
+
"smsMarketingConsent": {
|
|
308
|
+
"marketingState": "SUBSCRIBED",
|
|
309
|
+
"marketingOptInLevel": "SINGLE_OPT_IN",
|
|
310
|
+
"consentUpdatedAt": "2025-01-15T10:00:00Z"
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## Marketing Consent States
|
|
317
|
+
|
|
318
|
+
| State | Description |
|
|
319
|
+
|-------|-------------|
|
|
320
|
+
| `NOT_SUBSCRIBED` | Customer has not subscribed |
|
|
321
|
+
| `PENDING` | Awaiting confirmation (double opt-in) |
|
|
322
|
+
| `SUBSCRIBED` | Customer is subscribed |
|
|
323
|
+
| `UNSUBSCRIBED` | Customer has unsubscribed |
|
|
324
|
+
| `REDACTED` | Customer data has been redacted |
|
|
325
|
+
| `INVALID` | Invalid contact information |
|
|
326
|
+
|
|
327
|
+
## Opt-In Levels
|
|
328
|
+
|
|
329
|
+
| Level | Description |
|
|
330
|
+
|-------|-------------|
|
|
331
|
+
| `SINGLE_OPT_IN` | Subscribed without confirmation |
|
|
332
|
+
| `CONFIRMED_OPT_IN` | Subscribed with email/SMS confirmation |
|
|
333
|
+
| `UNKNOWN` | Opt-in level not specified |
|
|
334
|
+
|
|
335
|
+
## UTM Parameters
|
|
336
|
+
|
|
337
|
+
Track marketing attribution with UTM parameters:
|
|
338
|
+
|
|
339
|
+
| Parameter | Description |
|
|
340
|
+
|-----------|-------------|
|
|
341
|
+
| `campaign` | Campaign name |
|
|
342
|
+
| `source` | Traffic source (google, facebook, email) |
|
|
343
|
+
| `medium` | Marketing medium (cpc, banner, newsletter) |
|
|
344
|
+
| `term` | Paid search keywords |
|
|
345
|
+
| `content` | Differentiate similar content/links |
|
|
346
|
+
|
|
347
|
+
## API Scopes Required
|
|
348
|
+
|
|
349
|
+
- `read_marketing_events` - Read marketing events
|
|
350
|
+
- `write_marketing_events` - Create/update marketing events
|
|
351
|
+
- `read_customers` - Read customer marketing consent
|
|
352
|
+
- `write_customers` - Update customer marketing consent
|