{
  "openapi": "3.0.1",
  "info": {
    "title": "PlaceCall - AI phone calls to US businesses",
    "description": "Calls every business on your list, asks the questions you set, and returns a structured row per call. Gets what scraping cannot: whether they actually answer, and what they actually say.",
    "version": "0.1",
    "x-build-id": "c3hcnya8N9oHd0Cx1"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/voygr~placecall/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-voygr-placecall",
        "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/voygr~placecall/runs": {
      "post": {
        "operationId": "runs-sync-voygr-placecall",
        "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/voygr~placecall/run-sync": {
      "post": {
        "operationId": "run-sync-voygr-placecall",
        "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": {
          "acceptTerms": {
            "title": "PlaceCall terms (required to place calls)",
            "enum": [
              "I agree to the PlaceCall API Terms and Privacy Policy (version 2026-09-24)"
            ],
            "type": "string",
            "description": "By placing calls you agree to the PlaceCall <a href='https://voygr.tech/terms-api' target='_blank'>API Terms</a> and <a href='https://voygr.tech/privacy-policy' target='_blank'>Privacy Policy</a>. In short: call only on behalf of yourself or an organization you represent, and only for lawful purposes. Not needed for 'Check my list, don't call'."
          },
          "locations": {
            "title": "Businesses to call (JSON)",
            "type": "array",
            "description": "One object per business, e.g. [{\"name\": \"Corner Cafe\", \"phone\": \"(415) 555-0142\"}]. A US phone number is required in any common format; a name is recommended. Every other field you include is passed through to the output so results join back to your own data. A picked dataset, a CSV file or link, or pasted rows below are used instead, in that order."
          },
          "inputDatasetId": {
            "title": "…or a dataset",
            "type": "string",
            "description": "Use the output of a previous Actor run instead of pasting a list: another Actor's results, or a previous run of this one when retrying. When set, this wins over pasted businesses. Columns are detected automatically."
          },
          "csvFile": {
            "title": "…or a CSV file or link (needs a phone column)",
            "type": "string",
            "description": "Needs a column of US phone numbers. A business-name column helps: the agent says the name on the call. Every other column comes back with your results and can be used in questions as {column}. Upload a CSV or tab-separated file with a header row, or paste a link to one (a Google Sheet shared as 'Anyone with the link can view' works). Excel: save as CSV first."
          },
          "pastedRows": {
            "title": "…or paste rows from a spreadsheet (needs a phone column)",
            "type": "string",
            "description": "Copy the cells from Google Sheets or Excel, header row included, and paste them here. Needs a column of US phone numbers; a business-name column helps."
          },
          "questions": {
            "title": "Questions to ask every business",
            "type": "array",
            "description": "Asked of every business, one at a time. Two or three short factual questions work best. Use {column} to read a business its own data back, e.g. 'Is your address still {address}?' (any column from your list). Ready-made sets are in the README.",
            "items": {
              "type": "string"
            }
          },
          "dryRun": {
            "title": "Check my list, don't call",
            "type": "boolean",
            "description": "Reads your list and shows what would happen: the columns detected, the exact questions for each business, rows that would be skipped, your free calls left and the most it could cost. Nobody is called and nothing is charged. Untick to place the calls.",
            "default": false
          },
          "template": {
            "title": "Question set (API)",
            "type": "string",
            "description": "API only: a named question set used when 'questions' is empty: verify_hours, reservations, availability, new_customers, confirm_details. See the README."
          },
          "templateVariables": {
            "title": "Template variables",
            "type": "object",
            "description": "API only: values for {placeholders} filled once for the whole run, e.g. {\"item\": \"oat milk\"}. A value here wins over a column of the same name."
          },
          "context": {
            "title": "Why you are calling",
            "maxLength": 300,
            "type": "string",
            "description": "Optional one-line framing, e.g. 'verifying directory information for a listings site'. Helps the agent sound purposeful rather than cold."
          },
          "callerDisplayName": {
            "title": "Calling on whose behalf?",
            "maxLength": 80,
            "type": "string",
            "description": "The name the agent gives. Recommended - without it the call introduces itself generically, which businesses trust less."
          },
          "language": {
            "title": "Conversation language",
            "enum": [
              "auto",
              "en",
              "es",
              "fr",
              "de",
              "it",
              "pt",
              "nl",
              "ru",
              "hi",
              "ja",
              "sr",
              "tr",
              "pl"
            ],
            "type": "string",
            "description": "English is the most reliable; the rest are best-effort.",
            "default": "en"
          },
          "unattendedAnswer": {
            "title": "Answer if a call asks a question",
            "type": "string",
            "description": "Nobody is watching an Actor run, so if a business asks for a detail your questions did not cover, the agent has no one to ask. Put any facts it might need here. Every run also reports what it was asked."
          },
          "maxCalls": {
            "title": "Maximum calls this run (retries included)",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Upper bound on dials this run, retries included. The Actor also caps it at your key's own daily limit (25 on a free key, 5,000 after any purchase), which counts every attempt. First attempts get the budget before any retry, and businesses that never got a call come back as notAttempted with the reason.",
            "default": 100
          },
          "maxWaitSecsPerCall": {
            "title": "Give up on a call after (seconds)",
            "minimum": 60,
            "maximum": 900,
            "type": "integer",
            "description": "How long to follow a single call before moving on. Most calls finish well inside 180s.",
            "default": 300
          },
          "maxAttemptsPerBusiness": {
            "title": "Attempts per business",
            "minimum": 1,
            "maximum": 5,
            "type": "integer",
            "description": "1 means no retry. Retries only happen for the outcomes chosen below.",
            "default": 1
          },
          "retryOn": {
            "title": "Retry when the call ended as",
            "type": "array",
            "description": "Busy lines, technical failures and our own agent going silent are retried by default. A dropped call is retried only if nothing was answered before it dropped. A business that asks to be called back later always gets one callback, at the time it named. A business that hung up during or right after our introduction is never called again, whatever is selected here.",
            "items": {
              "type": "string",
              "enum": [
                "failed_busy",
                "failed_technical",
                "failed_agent_mute",
                "failed_no_answer",
                "failed_voicemail",
                "failed_call_dropped",
                "failed_no_agent_available",
                "failed_no_engagement",
                "failed_ivr_no_agent",
                "failed_recorded_announcement"
              ],
              "enumTitles": [
                "Line busy",
                "Technical failure",
                "Our agent went silent",
                "No answer",
                "Voicemail",
                "Call dropped before anything was answered",
                "Stuck on hold",
                "Picked up but never engaged",
                "Phone menu, no person reached",
                "Recorded announcement"
              ]
            },
            "default": [
              "failed_busy",
              "failed_technical",
              "failed_agent_mute"
            ]
          },
          "retryDelayMinutes": {
            "title": "Wait before retrying (minutes)",
            "minimum": 1,
            "maximum": 120,
            "type": "integer",
            "description": "Time between attempts to the same business. Calling back within a minute of a decline is the fastest way to get a number blocked. The run keeps running, and using Apify compute, while it waits, and every attempt must finish inside the run's Timeout (Run options, 1 hour by default): an attempt that would not is left for a later pass and its business comes back retryable.",
            "default": 5
          },
          "onlyRetryFailures": {
            "title": "Only call businesses not reached yet",
            "type": "boolean",
            "description": "When the dataset above is a previous run of this Actor, call only the businesses worth another try: not yet reached, not a hang-up during our introduction, not a call whose result was lost. Each row keeps its full attempt history. Each pass writes a new dataset, so the next pass should pick the newest one.",
            "default": false
          },
          "phoneField": {
            "title": "Phone column (override)",
            "type": "string",
            "description": "Only needed if auto-detection picks the wrong column."
          },
          "nameField": {
            "title": "Name column (override)",
            "type": "string",
            "description": "Only needed if auto-detection picks the wrong column for the business name."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}