{
  "openapi": "3.0.1",
  "info": {
    "title": "Upwork Scraper - Freelance Job Listings with Client Intel",
    "description": "Scrape Upwork jobs with full client intelligence — country, total spent, payment-verified, rating, reviews, and exact applicant count. 14 filters and incremental mode that emits only new or changed listings across runs.",
    "version": "0.6",
    "x-build-id": "UaIKpujZzTHCEOLKs"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/blackfalcondata~upwork-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-blackfalcondata-upwork-scraper",
        "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/blackfalcondata~upwork-scraper/runs": {
      "post": {
        "operationId": "runs-sync-blackfalcondata-upwork-scraper",
        "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/blackfalcondata~upwork-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-blackfalcondata-upwork-scraper",
        "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": {
          "query": {
            "title": "🔍 Search Term(s)",
            "type": "string",
            "description": "Job search keywords. Leave empty to browse all jobs."
          },
          "searchUrl": {
            "title": "🔗 Search URL (overrides other filters)",
            "type": "string",
            "description": "Paste a full Upwork search URL (https://www.upwork.com/nx/search/jobs/?q=...). Filters in the URL are auto-parsed and override individual fields."
          },
          "jobType": {
            "title": "💼 Job Type",
            "enum": [
              "hourly",
              "fixed"
            ],
            "type": "string",
            "description": "Filter by payment type."
          },
          "experienceLevel": {
            "title": "🎓 Experience Level",
            "enum": [
              "EntryLevel",
              "IntermediateLevel",
              "ExpertLevel"
            ],
            "type": "string",
            "description": "Filter by required experience."
          },
          "workload": {
            "title": "⏳ Workload",
            "enum": [
              "as_needed",
              "part_time",
              "full_time"
            ],
            "type": "string",
            "description": "Filter by time commitment."
          },
          "sort": {
            "title": "🔀 Sort Order",
            "enum": [
              "recency",
              "relevance",
              "newest",
              "oldest"
            ],
            "type": "string",
            "description": "How to sort results.",
            "default": "recency"
          },
          "category": {
            "title": "📁 Category",
            "uniqueItems": true,
            "type": "array",
            "description": "Upwork category name (e.g. \"Web Development\") or category2 UID, or an array of either.",
            "items": {
              "type": "string"
            }
          },
          "location": {
            "title": "🌍 Client Location (include)",
            "uniqueItems": true,
            "type": "array",
            "description": "Countries, regions, or structured entries. Accepts: country name (\"United States\"), ISO code (\"US\"), region name (\"europe\", \"north_america\", \"english_speaking\"), or {\"type\": \"COUNTRY\"|\"REGION\", \"value\": \"...\"}."
          },
          "excludeLocations": {
            "title": "🚫 Client Location (exclude)",
            "uniqueItems": true,
            "type": "array",
            "description": "Countries or regions to exclude. Same format as location."
          },
          "budget": {
            "title": "💰 Fixed-Price Budget Range",
            "enum": [
              "0-99",
              "100-499",
              "500-999",
              "1000-4999",
              "5000-"
            ],
            "type": "string",
            "description": "Filter fixed-price jobs by amount range (USD)."
          },
          "hourlyRate": {
            "title": "⏱️ Hourly Rate Range",
            "type": "string",
            "description": "Filter hourly jobs by rate (USD/hr). Format: \"min-max\", open-ended with trailing dash (\"50-\")."
          },
          "duration": {
            "title": "📅 Project Duration",
            "enum": [
              "week",
              "month",
              "semester",
              "ongoing"
            ],
            "type": "string",
            "description": "Filter by expected length."
          },
          "verifiedPaymentOnly": {
            "title": "✅ Payment-Verified Clients Only",
            "type": "boolean",
            "description": "Only show jobs from clients with a verified payment method.",
            "default": false
          },
          "proposals": {
            "title": "📊 Proposals Count (competition level)",
            "enum": [
              "0-4",
              "5-9",
              "10-14",
              "15-19",
              "20-49"
            ],
            "type": "string",
            "description": "Filter by number of proposals already submitted. Pick \"0-4\" for lowest competition."
          },
          "contractToHire": {
            "title": "🤝 Contract-to-Hire Only",
            "type": "boolean",
            "description": "Filter to jobs that may convert into a full-time hire.",
            "default": false
          },
          "clientHires": {
            "title": "📋 Client Hiring History",
            "enum": [
              "0",
              "1-9",
              "10+"
            ],
            "type": "string",
            "description": "Filter by how many freelancers the client has hired."
          },
          "includeKeywords": {
            "title": "📝 Include Keywords",
            "type": "object",
            "description": "Require at least one of these keywords in title/description/skills. Example: {\"keywords\":[\"React\",\"Node.js\"],\"matchTitle\":true,\"matchDescription\":true,\"matchSkills\":true}."
          },
          "excludeKeywords": {
            "title": "🚫 Exclude Keywords",
            "type": "object",
            "description": "Exclude jobs containing any of these keywords. Same config shape as includeKeywords."
          },
          "fromDate": {
            "title": "📅 From Date",
            "type": "string",
            "description": "Only include jobs published on or after this date. Accepts YYYY-MM-DD or ISO-8601."
          },
          "toDate": {
            "title": "📅 To Date",
            "type": "string",
            "description": "Only include jobs published on or before this date."
          },
          "maxAgeMinutes": {
            "title": "⏰ Max Age (minutes)",
            "minimum": 0,
            "type": "integer",
            "description": "Only include jobs posted within the last N minutes. 0 = no limit. Pairs well with scheduled runs.",
            "default": 0
          },
          "minClientTotalSpent": {
            "title": "💵 Min Client Total Spent (USD)",
            "minimum": 0,
            "type": "integer",
            "description": "Only include jobs from clients who have spent at least this much on Upwork.",
            "default": 0
          },
          "minClientRating": {
            "title": "⭐ Min Client Rating (0-5)",
            "minimum": 0,
            "maximum": 5,
            "type": "number",
            "description": "Only include clients with a rating at least this high.",
            "default": 0
          },
          "minClientReviewCount": {
            "title": "🗂️ Min Client Review Count",
            "minimum": 0,
            "type": "integer",
            "description": "Only include clients with at least this many reviews.",
            "default": 0
          },
          "customFilters": {
            "title": "🔧 Custom Filters (advanced)",
            "type": "array",
            "description": "Array of rules applied to any output field. Each rule: {\"field\":\"<name>\",\"op\":\"includes|notIncludes|equals|notEquals|gt|gte|lt|lte\",\"value\":...}. Example: [{\"field\":\"clientCountry\",\"op\":\"equals\",\"value\":\"United States\"}, {\"field\":\"description\",\"op\":\"notIncludes\",\"value\":\"wordpress\"}]."
          },
          "maxResults": {
            "title": "💯 Max Results",
            "minimum": 0,
            "maximum": 5050,
            "type": "integer",
            "description": "Maximum total results. 0 = unlimited. Upwork caps search depth at ~5050 results per query — narrow with filters for larger pools.",
            "default": 50
          },
          "descriptionMaxLength": {
            "title": "✂️ Description Max Length",
            "minimum": 0,
            "type": "integer",
            "description": "Truncate description to N characters. 0 = full text.",
            "default": 0
          },
          "compact": {
            "title": "📦 Compact Output (for AI/MCP)",
            "type": "boolean",
            "description": "Core fields only — trimmed for LLM pipelines.",
            "default": false
          },
          "incrementalMode": {
            "title": "♻️ Incremental Mode",
            "type": "boolean",
            "description": "Only output new/changed jobs since last run.",
            "default": false
          },
          "stateKey": {
            "title": "🔑 State Key",
            "type": "string",
            "description": "Unique identifier for this tracked search. Required when incrementalMode is true."
          },
          "skipReposts": {
            "title": "🚫 Skip Reposts",
            "type": "boolean",
            "description": "In incremental mode, skip jobs that appear to be reposts of previously-seen expired jobs (same content hash).",
            "default": false
          },
          "enrichDetails": {
            "title": "💎 Enrich With Details (requires session token)",
            "type": "boolean",
            "description": "Fetch the authenticated detail page per job to unlock ~30 extra fields: client timezone + city, industry, company size, total hires, hire rate, activity (totalHired, invites, last buyer activity), questions, attachments, allowed countries/English-level, min JSS, AI-generated description flag, work history with feedback. Each enriched job is billed as a separate PPE event. Pairs with incrementalMode to only enrich NEW/UPDATED jobs.",
            "default": false
          },
          "sessionToken": {
            "title": "🔐 Upwork Session Token",
            "type": "string",
            "description": "JWT Bearer token from the `oauth2_global_js_token` cookie in your logged-in Upwork session. MUST start with 'eyJ...' — tokens in the 'oauth2v2_int_XXXX' format are issued by the visitor OAuth2 client and DO NOT have scope for detail-page fields, so they will be rejected with field-permission errors. How to get the right token: (1) log in to upwork.com, (2) DevTools → Application → Cookies → upwork.com, (3) find cookie named `oauth2_global_js_token`, (4) copy its Value (long JWT starting with 'eyJ...'). Typically lives 24h. Treat as a password."
          },
          "detailConcurrency": {
            "title": "⚙️ Detail Fetch Concurrency",
            "minimum": 1,
            "maximum": 30,
            "type": "integer",
            "description": "Parallel requests when enriching. 5 is conservative; 10-20 works for small runs. Higher values increase risk of rate-limiting.",
            "default": 5
          },
          "telegramToken": {
            "title": "📱 Telegram Bot Token",
            "type": "string",
            "description": "Telegram bot token from @BotFather. Send notifications to a chat or channel when new jobs are emitted. Pairs well with incrementalMode for real-time alerts."
          },
          "telegramChatId": {
            "title": "💬 Telegram Chat / Channel ID",
            "type": "string",
            "description": "Chat ID (from @userinfobot) or channel ID (starts with -100 for channels). Required when telegramToken is set."
          },
          "discordWebhookUrl": {
            "title": "💬 Discord Webhook URL",
            "type": "string",
            "description": "Discord channel webhook URL (Server Settings → Integrations → Webhooks → New Webhook). Sends rich embeds with title, budget, client, applicants, and score per job."
          },
          "slackWebhookUrl": {
            "title": "💼 Slack Incoming Webhook URL",
            "type": "string",
            "description": "Slack incoming webhook URL (Slack App → Incoming Webhooks → Add New Webhook). Formats jobs as Slack blocks."
          },
          "whatsappPhoneNumberId": {
            "title": "📱 WhatsApp Phone Number ID",
            "type": "string",
            "description": "WhatsApp Business phone number ID from Meta Business Manager (the numeric ID next to your number — NOT the phone number itself). Free service-conversation messages within 24 hours of last user-initiated contact."
          },
          "whatsappAccessToken": {
            "title": "🔐 WhatsApp Access Token",
            "type": "string",
            "description": "Meta Cloud API access token with whatsapp_business_messaging scope. Get a permanent token from a system user in Meta Business Manager."
          },
          "whatsappTo": {
            "title": "📨 WhatsApp Recipient",
            "type": "string",
            "description": "Recipient phone number in E.164 format (e.g. +4512345678). The recipient must have messaged your business number within the last 24 hours."
          },
          "webhookUrl": {
            "title": "🪝 Generic Webhook URL",
            "type": "string",
            "description": "Universal escape hatch for n8n / Make / Zapier / custom HTTP backends. Receives a JSON POST { metadata, items } per run. Single attempt, 15 s timeout."
          },
          "webhookHeaders": {
            "title": "🪝 Webhook Headers (optional)",
            "type": "object",
            "description": "Additional HTTP headers sent with the generic webhook POST (e.g. {\"Authorization\":\"Bearer ...\"})."
          },
          "notificationLimit": {
            "title": "🔢 Notification Limit",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Maximum number of jobs to send per notification batch. Prevents spam on large result sets.",
            "default": 5
          },
          "includeRunMetadata": {
            "title": "📣 Include Run Summary in Notifications",
            "type": "boolean",
            "description": "Prepend a one-line summary (query + total count) to each notification batch.",
            "default": true
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}