{
  "openapi": "3.0.1",
  "info": {
    "title": "Sonny Angel Restock Tracker — Stock Checker & Restock Alerts",
    "description": "Get a Discord or webhook alert the moment Sonny Angel figures restock on the official US store or any Shopify store. Tracks every series and box variant, diffs each run against the last, and outputs only what changed. Schedule it every few minutes for a Shopify inventory monitor.",
    "version": "0.1",
    "x-build-id": "PVF65OBFvoGSarp2M"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scrapelabmax~sonny-angel-restock-tracker/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scrapelabmax-sonny-angel-restock-tracker",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/scrapelabmax~sonny-angel-restock-tracker/runs": {
      "post": {
        "operationId": "runs-sync-scrapelabmax-sonny-angel-restock-tracker",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/scrapelabmax~sonny-angel-restock-tracker/run-sync": {
      "post": {
        "operationId": "run-sync-scrapelabmax-sonny-angel-restock-tracker",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "storeUrls": {
            "title": "Store URLs",
            "type": "array",
            "description": "Any Shopify store, e.g. <code>https://www.sonnyangelusa.com</code> (the official Sonny Angel USA store, used by default). Paste the home page, or a collection page such as <code>https://shop.com/collections/sonny-angel</code> to poll just that collection (much cheaper on big stores). Bare domains work too. Each store is checked and diffed separately. May be empty if you tick retailers below.",
            "default": [
              "https://www.sonnyangelusa.com"
            ],
            "items": {
              "type": "string"
            }
          },
          "retailerPresets": {
            "title": "Also check these retailers",
            "type": "array",
            "description": "Sonny Angel retailers on the official retailer list that run Shopify, polled through their Sonny Angel collection. Each ticked store adds one catalog check per run.",
            "items": {
              "type": "string",
              "enum": [
                "kinokuniya-usa",
                "japanla",
                "senpais-corner",
                "friends-nyc",
                "gunnzo",
                "leanna-lins-wonderland",
                "world-of-mirth",
                "peace-love-happiness-club",
                "kiddywampus",
                "colorful-cute"
              ],
              "enumTitles": [
                "Kinokuniya USA",
                "JapanLA (Los Angeles)",
                "Senpai's Corner (Virginia)",
                "Friends NYC",
                "Gunnzo (San Diego)",
                "Leanna Lin's Wonderland (Los Angeles)",
                "World of Mirth (Richmond, VA)",
                "Peace Love & Happiness Club (Washington)",
                "Kiddywampus (Minnesota)",
                "Colorful Cute (Florida)"
              ]
            },
            "default": []
          },
          "brandKeyword": {
            "title": "Brand keyword",
            "type": "string",
            "description": "Only products whose tags, vendor, product type or title contain this keyword are tracked (case-insensitive). Keep <code>Sonny Angel</code> for multi-brand retailers; enter <code>*</code> to track every product in the store.",
            "default": "Sonny Angel"
          },
          "seriesFilter": {
            "title": "Series filter",
            "type": "array",
            "description": "Only track products matching any of these keywords, e.g. <code>Hipper</code>, <code>Animal Series</code>, <code>Christmas</code>. Matched case-insensitively against the title, option, series and tags. Leave empty to track every series.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "fullCatalog": {
            "title": "Output the full catalog",
            "type": "boolean",
            "description": "Off: the dataset only gets rows that changed since the last run (restocked, sold out, new, removed). On: every tracked variant is written on every run, with its change type.",
            "default": false
          },
          "alertOnNewProducts": {
            "title": "Alert on new products",
            "type": "boolean",
            "description": "Also alert when a product that was never seen before shows up already in stock (a new drop). Restocks always alert.",
            "default": true
          },
          "discordWebhookUrl": {
            "title": "Discord webhook URL",
            "type": "string",
            "description": "Post restock alerts to a Discord channel. In Discord: channel settings → Integrations → Webhooks → New Webhook → Copy Webhook URL. It looks like <code>https://discord.com/api/webhooks/123/abc</code>. Alerts say \"reported in stock\": the store's stock flag can lag checkout, so a purchase is never guaranteed."
          },
          "webhookUrl": {
            "title": "Webhook URL",
            "type": "string",
            "description": "Any HTTP(S) endpoint (Zapier, Make, n8n, your own server). When something restocks it receives a JSON POST: <code>{ \"event\": \"restock\", \"storeUrls\": [...], \"scrapedAt\": \"...\", \"items\": [...] }</code> where items are the same rows as the dataset."
          },
          "snapshotStoreName": {
            "title": "Snapshot store name",
            "type": "string",
            "description": "Named key-value store in your Apify account that remembers stock between runs. <b>Keep it the same between scheduled runs</b>, or every run starts over as a baseline (no alerts). Use a different name per schedule if you run several configurations. Letters, digits and dashes only.",
            "default": "sonny-angel-snapshot"
          },
          "currency": {
            "title": "Currency",
            "type": "string",
            "description": "Three-letter currency code of the store's prices, e.g. <code>USD</code>, <code>CAD</code>, <code>GBP</code>. Shopify's public catalog does not report it, so set it to match the store.",
            "default": "USD"
          },
          "maxPages": {
            "title": "Max catalog pages",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "Maximum catalog pages fetched per store (250 products each). 10 covers 2,500 products, plenty for most stores.",
            "default": 10
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Off by default because Shopify's catalog JSON rarely blocks, so you pay no proxy cost. If runs start failing with 403 or 429 errors, switch to Apify datacenter proxy, or residential as a last resort.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}