{
  "openapi": "3.0.1",
  "info": {
    "title": "BidDelta — SAM.gov Material Change Monitor",
    "description": "Free beta for capture and proposal teams: BidDelta compares saved SAM.gov opportunity snapshots and flags deadline, status, contact, award, and attachment-metadata changes with source-linked before-and-after evidence. No BidDelta fee; Apify usage applies. Contact: contact@optimusconnections.net",
    "version": "0.3",
    "x-build-id": "B7kyZ4lE91jwaNxwG"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/optimus-connections~bid-delta/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-optimus-connections-bid-delta",
        "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/optimus-connections~bid-delta/runs": {
      "post": {
        "operationId": "runs-sync-optimus-connections-bid-delta",
        "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/optimus-connections~bid-delta/run-sync": {
      "post": {
        "operationId": "run-sync-optimus-connections-bid-delta",
        "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": {
          "mode": {
            "title": "Mode",
            "enum": [
              "monitor",
              "try-sample"
            ],
            "type": "string",
            "description": "Start with the sample if you just want to see what an alert looks like.",
            "default": "monitor"
          },
          "watch": {
            "title": "Solicitations to watch",
            "type": "array",
            "description": "Paste SAM.gov links (https://sam.gov/opp/…/view), notice IDs, or solicitation numbers — one per line. The first run saves a baseline; later runs report changes. Entries that can't be found are listed in the run output and don't fail the run.",
            "items": {
              "type": "string"
            }
          },
          "searches": {
            "title": "Also watch searches (optional)",
            "type": "array",
            "description": "Catch new matching opportunities and changes to them. Each profile needs at least one filter: keywords, naicsCode, state (2-letter), setAsideCode (e.g. SBA, 8A, SDVOSBC, WOSB, HZC), noticeTypes (o=solicitation, p=presolicitation, k=combined, r=sources sought, a=award). Newest 25 matches per search.",
            "items": {
              "type": "object"
            },
            "default": []
          },
          "notifyEmail": {
            "title": "📧 Email",
            "type": "string",
            "description": "Send alerts to this address (via Apify's send-mail Actor)."
          },
          "slackWebhookUrl": {
            "title": "💬 Slack incoming webhook URL",
            "type": "string",
            "description": "https://hooks.slack.com/services/… (Slack → Apps → Incoming Webhooks)."
          },
          "teamsWebhookUrl": {
            "title": "🟦 Microsoft Teams webhook URL",
            "type": "string",
            "description": "Teams channel → ⋯ → Workflows → 'Post to a channel when a webhook request is received'; paste the URL."
          },
          "discordWebhookUrl": {
            "title": "🎮 Discord webhook URL",
            "type": "string",
            "description": "Server settings → Integrations → Webhooks → New → Copy URL."
          },
          "telegramBotToken": {
            "title": "✈️ Telegram bot token",
            "type": "string",
            "description": "Create a bot with @BotFather and paste its token. Also fill Telegram chat ID."
          },
          "telegramChatId": {
            "title": "✈️ Telegram chat ID",
            "type": "string",
            "description": "Your user/group chat ID (message your bot, then open https://api.telegram.org/bot<token>/getUpdates)."
          },
          "ntfyTopic": {
            "title": "🔔 ntfy push topic",
            "type": "string",
            "description": "Free phone push with no account: install the ntfy app and subscribe to a long random topic name, e.g. biddelta-7f3k9q2x. Anyone who knows the topic can read it, so make it hard to guess."
          },
          "ntfyServer": {
            "title": "🔔 ntfy server",
            "type": "string",
            "description": "Default https://ntfy.sh. Self-hosted works too."
          },
          "ntfyToken": {
            "title": "🔔 ntfy access token (optional)",
            "type": "string",
            "description": "For protected topics or self-hosted servers."
          },
          "pushoverUserKey": {
            "title": "📱 Pushover user key",
            "type": "string",
            "description": "From your Pushover dashboard."
          },
          "pushoverAppToken": {
            "title": "📱 Pushover application API token",
            "type": "string",
            "description": "Create an application at pushover.net/apps/build."
          },
          "smsProvider": {
            "title": "📟 SMS provider",
            "enum": [
              "none",
              "twilio",
              "telnyx"
            ],
            "type": "string",
            "description": "Bring your own account; the provider bills you per SMS (≈$0.008–0.01 each in the US). Only urgent changes are texted (see SMS minimum severity).",
            "default": "none"
          },
          "smsAccountId": {
            "title": "📟 Twilio Account SID",
            "type": "string",
            "description": "Starts with AC. Not needed for Telnyx."
          },
          "smsAuthToken": {
            "title": "📟 Twilio auth token / Telnyx API key",
            "type": "string",
            "description": "Stored encrypted by Apify."
          },
          "smsFrom": {
            "title": "📟 From number",
            "type": "string",
            "description": "Your Twilio/Telnyx number in +E.164 format, e.g. +15551234567."
          },
          "smsTo": {
            "title": "📟 Send texts to",
            "type": "array",
            "description": "Up to 5 numbers in +E.164 format.",
            "items": {
              "type": "string"
            }
          },
          "smsMinSeverity": {
            "title": "📟 SMS minimum severity",
            "enum": [
              "critical",
              "high",
              "medium"
            ],
            "type": "string",
            "description": "Only changes at or above this level are texted. Default: high.",
            "default": "high"
          },
          "googleSheetsWebhookUrl": {
            "title": "📊 Google Sheets: Apps Script web-app URL",
            "type": "string",
            "description": "Appends one row per change to your sheet. Paste the 15-line script from the README (Channel setup guide) into Extensions → Apps Script, deploy as web app, paste the /exec URL."
          },
          "calendarFeed": {
            "title": "📅 Deadline calendar feed (.ics)",
            "type": "boolean",
            "description": "Keeps a subscribable calendar of every watched response deadline (with a 2-day reminder) that updates when deadlines move. The URL is in OUTPUT.calendarFeedUrl and in email alerts.",
            "default": true
          },
          "googleCalendarWebhookUrl": {
            "title": "📅 Google Calendar: Apps Script web-app URL (optional)",
            "type": "string",
            "description": "Creates/updates events directly in your Google Calendar when a deadline changes. Script in the README (Channel setup guide)."
          },
          "webhookUrl": {
            "title": "🔗 Generic webhook (Make, Zapier, n8n, your app)",
            "type": "string",
            "description": "https URL that receives JSON {monitorId, eventCount, summary, events[]}."
          },
          "alertMinSeverity": {
            "title": "Alert minimum severity",
            "enum": [
              "medium",
              "high",
              "critical"
            ],
            "type": "string",
            "description": "Applies to all channels (SMS also has its own floor).",
            "default": "medium"
          },
          "notifyWhenNoChanges": {
            "title": "Also ping when nothing changed",
            "type": "boolean",
            "description": "Handy for testing your channels or for a daily 'all quiet' heartbeat.",
            "default": false
          },
          "schedulePreset": {
            "title": "How often will you schedule it?",
            "enum": [
              "hourly",
              "every-4-hours",
              "twice-daily",
              "daily",
              "weekdays-8am"
            ],
            "type": "string",
            "description": "Used to show a cron line and a cost estimate in the run output. Create the schedule in Apify Console → Schedules. Cost is Apify usage only; BidDelta is free during beta.",
            "default": "twice-daily"
          },
          "openaiApiKey": {
            "title": "AI summaries: OpenAI-compatible API key (optional)",
            "type": "string",
            "description": "Plain-English summaries are built in and free. Add your own key only if you want an AI rewrite of each change (gpt-4o-mini by default; roughly $0.0001 per change on your LLM bill). Leave empty to keep it free."
          },
          "aiModel": {
            "title": "AI model",
            "type": "string",
            "description": "Any OpenAI-compatible chat model name.",
            "default": "gpt-4o-mini"
          },
          "monitorId": {
            "title": "Monitor ID",
            "pattern": "^[a-z0-9][a-z0-9-]{2,62}$",
            "type": "string",
            "description": "Name of this watch's saved state. Use a different ID for each separate watchlist. Changing it starts a new baseline.",
            "default": "my-watch"
          },
          "sourceMode": {
            "title": "Data source",
            "enum": [
              "auto",
              "public",
              "sam-api",
              "fixture"
            ],
            "type": "string",
            "description": "Auto uses public SAM.gov data, or the official API if you provide a key and no watchlist.",
            "default": "auto"
          },
          "samApiKey": {
            "title": "SAM.gov API key (optional)",
            "type": "string",
            "description": "Your own SAM.gov public API key. Apify encrypts this value at rest and decrypts it only inside your Actor run. A private deployment may alternatively provide SAM_GOV_API_KEY as a secret environment variable."
          },
          "dryRun": {
            "title": "Dry run",
            "type": "boolean",
            "description": "Free beta: keep on. No BidDelta charges are made either way during beta.",
            "default": true
          },
          "emitBaseline": {
            "title": "Emit initial baseline as events",
            "type": "boolean",
            "description": "(Legacy/advanced) Demonstration-only. Official API mode always establishes its first successful baseline silently and without a material-event charge.",
            "default": true
          },
          "fixtureData": {
            "title": "Fixture data",
            "type": "array",
            "description": "(Legacy/advanced) Optional SAM-style records for no-network testing.",
            "default": [
              {
                "noticeId": "11111111-1111-1111-1111-111111111111",
                "title": "Sample HVAC Preventive Maintenance",
                "solicitationNumber": "SAMPLE-HVAC-001",
                "postedDate": "2026-08-20",
                "responseDeadLine": "2026-09-22T17:00:00-05:00",
                "active": "Yes",
                "type": "Solicitation",
                "naicsCode": "238220",
                "uiLink": "https://sam.gov/"
              }
            ]
          },
          "maxPagesPerSearch": {
            "title": "Maximum pages per search",
            "minimum": 1,
            "maximum": 50,
            "type": "integer",
            "description": "(Legacy/advanced) Safety cap for pagination. If the result set exceeds this cap, the run fails closed and does not advance monitor state.",
            "default": 10
          },
          "missingThreshold": {
            "title": "Missing-observation threshold",
            "minimum": 2,
            "maximum": 10,
            "type": "integer",
            "description": "(Legacy/advanced) How many consecutive successful queries must miss a previously matched notice before emitting a non-cancellation missing signal.",
            "default": 2
          },
          "notifications": {
            "title": "(Legacy v0.3.0) Alerts object",
            "type": "object",
            "description": "Deprecated; use the fields above. Still honored."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}