{
  "openapi": "3.0.1",
  "info": {
    "title": "Building Permit Lead Finder — ProjectTrigger",
    "description": "Turns official public building-permit data into ranked, explainable opportunity signals for the service you sell.",
    "version": "0.1",
    "x-build-id": "rUVGP6KkKFO9fNqv1"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/ayalalabs~projecttrigger/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-ayalalabs-projecttrigger",
        "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/ayalalabs~projecttrigger/runs": {
      "post": {
        "operationId": "runs-sync-ayalalabs-projecttrigger",
        "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/ayalalabs~projecttrigger/run-sync": {
      "post": {
        "operationId": "run-sync-ayalalabs-projecttrigger",
        "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",
        "required": [
          "serviceType",
          "market"
        ],
        "properties": {
          "serviceType": {
            "title": "What do you sell?",
            "enum": [
              "roofing",
              "hvac",
              "solar",
              "commercial_cleaning",
              "security_low_voltage",
              "drone_aerial",
              "custom"
            ],
            "type": "string",
            "description": "Every project is scored for this service, so the same permit ranks differently depending on your trade.",
            "default": "roofing"
          },
          "market": {
            "title": "Where?",
            "enum": [
              "orlando_fl",
              "central_florida",
              "brevard_county_fl"
            ],
            "type": "string",
            "description": "Orlando is read from an official open-data API and answers in seconds. Brevard County is read from its public permit portal one permit at a time, so including it makes a run take a few minutes. Central Florida searches both together and ranks them as one list. Each run reports which jurisdictions were searched and which have no public data feed.",
            "default": "orlando_fl"
          },
          "lookbackDays": {
            "title": "How fresh should the opportunities be?",
            "minimum": 1,
            "maximum": 365,
            "type": "integer",
            "description": "Only include permits filed or issued within this many days. Shorter is fresher; longer returns more.",
            "default": 30
          },
          "minimumProjectValue": {
            "title": "Minimum project value",
            "minimum": 0,
            "type": "integer",
            "description": "Skip projects below this declared construction value. Set 0 to include projects where the city recorded no value.",
            "default": 25000
          },
          "propertyType": {
            "title": "Which property types?",
            "enum": [
              "commercial",
              "residential",
              "all"
            ],
            "type": "string",
            "description": "Commercial also covers multifamily buildings of 3+ units, which are commercial opportunities for most trades.",
            "default": "commercial"
          },
          "minimumScore": {
            "title": "Minimum opportunity relevance score",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Higher numbers return fewer but stronger matches. 60 is a good starting point; try 75 for a short, high-confidence shortlist.",
            "default": 60
          },
          "maxResults": {
            "title": "Maximum opportunities",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "The highest-scoring projects come first, so a smaller number still gives you the best ones.",
            "default": 50
          },
          "customService": {
            "title": "Describe your service",
            "type": "string",
            "description": "Only used when 'What do you sell?' is set to Custom Service. Example: parking lot striping and sealcoating for retail centers."
          },
          "includeKeywords": {
            "title": "Keywords to prioritise",
            "uniqueItems": true,
            "type": "array",
            "description": "Projects mentioning any of these rank higher. Required for Custom Service; optional otherwise. Example: warehouse, hotel, distribution.",
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Keywords to exclude",
            "uniqueItems": true,
            "type": "array",
            "description": "Drop projects mentioning any of these. Example: fence, pool, shed.",
            "items": {
              "type": "string"
            }
          },
          "feedback": {
            "title": "Report what happened to past opportunities",
            "type": "array",
            "description": "Optional. Tell ProjectTrigger how earlier opportunities turned out and it stops showing them, favours contractors you have won work with, and reports how each grade actually performed. One object per permit; outcome is one of won, quoted, contacted, no_fit, unreachable. Example: [{\"permitNumber\": \"BLD2026-17192\", \"outcome\": \"won\", \"valueUsd\": 4200}]"
          },
          "hideActionedOpportunities": {
            "title": "Hide opportunities I have already actioned",
            "type": "boolean",
            "description": "Keeps anything you marked won, quoted, no_fit or unreachable off future lists. Anything marked only 'contacted' keeps appearing, since that conversation is still live.",
            "default": true
          },
          "backfillContactInfo": {
            "title": "Fill in missing phone numbers",
            "type": "boolean",
            "description": "When a permit names a contractor but no phone, look up the number that contractor published on their other permits in the same official dataset. Results are labelled so you always know where a number came from and how recent it is.",
            "default": true
          },
          "enrichmentEnabled": {
            "title": "Look up each contractor's business details",
            "type": "boolean",
            "description": "Off by default because it calls a paid Google Maps Actor and adds cost to every run. When on, ProjectTrigger tries to match the top opportunities' contractors to their public business listing, adding website, business phone, rating, categories and public role emails such as info@ or estimating@. A contractor is only resolved when the evidence is strong; an uncertain match is reported as AMBIGUOUS and left blank rather than guessed.",
            "default": false
          },
          "maxEnrichmentCandidates": {
            "title": "How many opportunities to enrich",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Only the highest-scoring opportunities are looked up. This is the main cost lever.",
            "default": 20
          },
          "minimumScoreForEnrichment": {
            "title": "Only enrich opportunities scoring at least",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Weak leads are not worth paying to research.",
            "default": 70
          },
          "maxEnrichmentSpendUsd": {
            "title": "Maximum enrichment spend per run (USD)",
            "minimum": 0,
            "type": "integer",
            "description": "Hard ceiling passed to the business-lookup Actor. It cannot charge more than this in one run.",
            "default": 1
          },
          "websiteEnrichmentEnabled": {
            "title": "Also read the business website",
            "type": "boolean",
            "description": "Reads up to four pages of a resolved business's own site to find its public contact email, contact page and social profiles. No personal addresses are collected.",
            "default": true
          },
          "enrichmentActorId": {
            "title": "Business lookup Actor (advanced)",
            "type": "string",
            "description": "Override the Google Maps Actor used for business lookups. Leave blank to use the default."
          }
        }
      },
      "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}