{
  "openapi": "3.0.1",
  "info": {
    "title": "PhD, Postdoc & Research Jobs Scraper — 12 Sources in 1",
    "description": "Every PhD, postdoc and research job source behind one endpoint: EURAXESS, jobs.ac.uk, UN Careers, ReliefWeb, Impactpool, Devex, Ikerbasque, EURES, LinkedIn, AcademicPositions + 2 university boards. One run returns a merged, deduped dataset - billed once. Incremental mode surfaces only new postings.",
    "version": "0.1",
    "x-build-id": "uxbKiwaZixw4AGVuR"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/nomad-agent~researcher-bundle/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-nomad-agent-researcher-bundle",
        "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/nomad-agent~researcher-bundle/runs": {
      "post": {
        "operationId": "runs-sync-nomad-agent-researcher-bundle",
        "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/nomad-agent~researcher-bundle/run-sync": {
      "post": {
        "operationId": "run-sync-nomad-agent-researcher-bundle",
        "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": {
          "sources": {
            "title": "Sources",
            "type": "array",
            "description": "Which boards to include. Leave empty to run the default set (all 11 boards that run inside this Actor — one flat bill, no extra fees). 'AcademicPositions' is the one exception: it needs a real browser to clear Cloudflare, so it runs as a separate child Actor and adds that Actor's own start + per-result fees on top of this bundle's. It is off by default; tick it only if you want it. 'Devex' and 'UB doctoral' additionally need the Anthropic, Mistral or OpenAI API key below (any one); without a key they are skipped, you are not charged for them, and a warning row explaining why is added to the results.",
            "items": {
              "type": "string",
              "enum": [
                "euraxess",
                "jobs_ac_uk",
                "ikerbasque",
                "math_ku_phd",
                "ub_doctoral",
                "academicpositions",
                "un_careers",
                "reliefweb",
                "impactpool",
                "devex",
                "linkedin",
                "eures"
              ],
              "enumTitles": [
                "EURAXESS — EU research jobs",
                "jobs.ac.uk — UK academic jobs",
                "Ikerbasque — Basque research fellowships",
                "University of Copenhagen — PhD positions",
                "Universitat de Barcelona — doctoral (needs AI key)",
                "AcademicPositions.com (extra child-Actor fees)",
                "UN Careers",
                "ReliefWeb — humanitarian jobs",
                "Impactpool — impact / IO careers",
                "Devex — global development (needs AI key)",
                "LinkedIn",
                "EURES — EU public employment network"
              ]
            },
            "default": [
              "euraxess",
              "jobs_ac_uk",
              "ikerbasque",
              "math_ku_phd",
              "ub_doctoral",
              "un_careers",
              "reliefweb",
              "impactpool",
              "devex",
              "linkedin",
              "eures"
            ]
          },
          "keyword": {
            "title": "Keyword",
            "type": "string",
            "description": "Optional free-text filter forwarded to the boards that support it (the others ignore it). E.g. 'machine learning', 'climate', 'postdoc'."
          },
          "incrementalMode": {
            "title": "Only new since last run",
            "type": "boolean",
            "description": "Return only postings this bundle has NOT already delivered on a previous run. The bundle remembers every listing URL it returned (in a private key-value store on your own Apify account) and, on later runs, skips — and does not re-charge its per-result fee for — anything you already received. The first run always returns everything; leave this off for a full snapshot each run, turn it on for a scheduled (e.g. daily/weekly) job that should surface only fresh postings.",
            "default": false
          },
          "anthropicApiKey": {
            "title": "Anthropic API key (fallback for 2 of 12 sources)",
            "type": "string",
            "description": "Optional fallback for 'Devex' and 'UB doctoral' when no Mistral key is supplied — they use an AI provider to extract listings. Without any key those two sources are skipped (you are not charged for them) and a warning row is added to the output explaining why; every other source runs normally either way. Usage is billed separately by Anthropic, not by this Actor."
          },
          "mistralApiKey": {
            "title": "Mistral API key (preferred for 2 of 12 sources)",
            "type": "string",
            "description": "Preferred key for 'Devex' and 'UB doctoral'. If more than one of Mistral, Anthropic and OpenAI keys are supplied, the bundle uses Mistral for those sources. Without any key those two sources are skipped and a warning row is added explaining why. Usage is billed separately by Mistral, not by this Actor."
          },
          "mistralModel": {
            "title": "Mistral model",
            "enum": [
              "mistral-small-latest",
              "mistral-medium-latest",
              "mistral-large-latest"
            ],
            "type": "string",
            "description": "Mistral model used for 'Devex' and 'UB doctoral' when mistralApiKey is supplied. Small is the default — it matches larger Mistral models on this task at a fraction of the cost.",
            "default": "mistral-small-latest"
          },
          "openaiApiKey": {
            "title": "OpenAI API key (alternative for 2 of 12 sources)",
            "type": "string",
            "description": "Alternative to anthropicApiKey/mistralApiKey for 'Devex' and 'UB doctoral' — pass this instead if you'd rather bring an OpenAI key (Mistral, then Anthropic, are preferred when more than one key is set). Without any key those two sources are skipped and a warning row is added explaining why. Usage is billed separately by OpenAI, not by this Actor."
          },
          "openaiModel": {
            "title": "OpenAI model",
            "type": "string",
            "description": "OpenAI model used for 'Devex' and 'UB doctoral' when openaiApiKey is the key in effect. Defaults to gpt-4.1-mini — cheap and fast for this task. Any chat-completions model works, including the gpt-5 family.",
            "default": "gpt-4.1-mini"
          },
          "maxItemsPerSource": {
            "title": "Max items per source",
            "type": "integer",
            "description": "Cap on items fetched from EACH board before merging. Raise it for a deeper sweep of every board; the merged total is still bounded by 'Max items (total)' below.",
            "default": 20
          },
          "maxItems": {
            "title": "Max items (total)",
            "type": "integer",
            "description": "Hard cap on the merged, deduped output — and therefore on what you pay, since this Actor charges per unique job returned. Default (240) is sources × 'Max items per source'. Set 0 to remove the cap; cost then scales with every board's raw output.",
            "default": 240
          },
          "cacheTtlSeconds": {
            "title": "Cache time (seconds)",
            "type": "integer",
            "description": "How long to reuse results already fetched from a board instead of fetching again. Set 0 to always fetch fresh data.",
            "default": 1800
          },
          "concurrency": {
            "title": "Concurrency",
            "type": "integer",
            "description": "How many boards to fetch at the same time. The default fetches them all at once, so a run takes as long as the slowest board rather than the sum.",
            "default": 12
          },
          "runTimeoutSecs": {
            "title": "Per-source timeout (seconds)",
            "type": "integer",
            "description": "How long to wait for each board before giving up on it and merging what the others returned. Boards run in parallel, so this is a per-board ceiling, not a budget shared across them.",
            "default": 240
          },
          "apifyToken": {
            "title": "Apify API token",
            "type": "string",
            "description": "Leave empty — injected automatically when this Actor runs on the Apify platform. Only set this when running the code outside the platform, e.g. on your own machine."
          },
          "actorOwner": {
            "title": "Actor owner",
            "type": "string",
            "description": "Only used to address the 'AcademicPositions' child Actor. Leave empty to use the published one — set it only if you run your own fork under a different Apify account.",
            "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}