{
  "openapi": "3.0.1",
  "info": {
    "title": "EURAXESS Jobs Scraper — EU Research Positions",
    "description": "Extract research vacancies from EURAXESS, the EU's researcher mobility portal: PhD, postdoc, fellowship and faculty roles across Europe. Each record carries title, institution, country, research field, contract type, deadline and apply URL. New-only delta alerts, no login required.",
    "version": "0.1",
    "x-build-id": "OMIpeGR8hS3grLM0V"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/nomad-agent~euraxess-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-nomad-agent-euraxess-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/nomad-agent~euraxess-scraper/runs": {
      "post": {
        "operationId": "runs-sync-nomad-agent-euraxess-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/nomad-agent~euraxess-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-nomad-agent-euraxess-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": {
          "keyword": {
            "title": "Keyword",
            "type": "string",
            "description": "Free-text search across job titles and descriptions (e.g. <code>machine learning</code>, <code>postdoc biology</code>). Leave empty to return all current job offers."
          },
          "countryFilter": {
            "title": "Country filter",
            "type": "string",
            "description": "Optional case-insensitive substring match on the posting country, applied client-side. E.g. <code>germany</code>, <code>france</code>, <code>spain</code>."
          },
          "postedSince": {
            "title": "Posted within (days)",
            "minimum": 0,
            "maximum": 365,
            "type": "integer",
            "description": "Only return job offers posted within this many days (applied client-side after fetch — EURAXESS listings are already sorted newest first). Leave at 0 to return all current offers regardless of posting date.",
            "default": 0
          },
          "titleExclude": {
            "title": "Title must NOT contain",
            "type": "array",
            "description": "Skip listings whose title contains any of these case-insensitive terms.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "companyExclude": {
            "title": "Company must NOT contain",
            "type": "array",
            "description": "Skip listings whose company name contains any of these case-insensitive terms.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "maxItems": {
            "title": "Max items",
            "minimum": 0,
            "maximum": 500,
            "type": "integer",
            "description": "Maximum number of job offers to return. Each returned job is a billed result — see the Pricing tab. Set to 0 for no limit (the source exposes roughly 500 current offers per query).",
            "default": 100
          },
          "onlyNewSinceLastRun": {
            "title": "Only new since last run (delta mode)",
            "type": "boolean",
            "description": "Delta / alert mode: only output postings not seen on a previous run that also had this flag on — the cheapest way to schedule this Actor on a cron and pay only for genuinely new research openings. Already-seen postings are dropped before push (not billed). State is tracked per Actor in a dedicated key-value store, keyed by each posting's EURAXESS node id. New rows carry <code>isNew: true</code>. See README \"Delta mode / alerts\".",
            "default": false
          },
          "translateKeywords": {
            "title": "Translate keyword into EU languages",
            "type": "boolean",
            "description": "When on, expands your <b>Keyword</b> into its equivalents across the major EU research languages (German, French, Spanish, Italian…) via the Anthropic or Mistral API, then matches any of them against each listing — so a search for <code>postdoc</code> also catches local-language titles like <code>Postdoktorand</code> or <code>investigador postdoctoral</code>. Requires your own API key below (BYOK); if turned on without one, the run falls back to a normal keyword search and says so. Off by default.",
            "default": false
          },
          "aiProvider": {
            "title": "AI provider",
            "enum": [
              "anthropic",
              "mistral",
              "openai"
            ],
            "type": "string",
            "description": "Which AI provider runs keyword translation (only relevant when \"Translate keyword\" is on). <code>anthropic</code> (default) uses Claude via anthropicApiKey. <code>mistral</code> uses a Mistral model via mistralApiKey instead — pick this if you'd rather bring a Mistral key than an Anthropic one. <code>openai</code> uses a GPT model via openaiApiKey.",
            "default": "anthropic"
          },
          "anthropicApiKey": {
            "title": "Anthropic API key",
            "type": "string",
            "description": "Your Anthropic API key (sk-ant-…). Only used when \"Translate keyword\" is on and aiProvider is <code>anthropic</code>; billed separately by Anthropic. Not required unless translateKeywords is on."
          },
          "aiModel": {
            "title": "Translation model (Anthropic)",
            "enum": [
              "claude-haiku-4-5-20251001",
              "claude-sonnet-4-5"
            ],
            "type": "string",
            "description": "Claude model used for keyword translation when aiProvider is <code>anthropic</code> (only relevant when \"Translate keyword\" is on). Haiku is fast, cheap and ample for this short translation task; Sonnet gives higher-quality readings on unusual or multi-word phrases.",
            "default": "claude-haiku-4-5-20251001"
          },
          "mistralApiKey": {
            "title": "Mistral API key",
            "type": "string",
            "description": "Your Mistral API key. Only used when \"Translate keyword\" is on and aiProvider is <code>mistral</code>; billed separately by Mistral. Not required unless translateKeywords is on with aiProvider=mistral."
          },
          "mistralModel": {
            "title": "Translation model (Mistral)",
            "enum": [
              "mistral-small-latest",
              "mistral-medium-latest",
              "mistral-large-latest"
            ],
            "type": "string",
            "description": "Mistral model used for keyword translation when aiProvider is <code>mistral</code> (only relevant when \"Translate keyword\" is on). Small is the default — it matches larger Mistral models on this well-scoped translation task at a fraction of the cost.",
            "default": "mistral-small-latest"
          },
          "openaiApiKey": {
            "title": "OpenAI API key",
            "type": "string",
            "description": "Your OpenAI API key (sk-…). Only used when \"Translate keyword\" is on and aiProvider is <code>openai</code>; billed separately by OpenAI. Not required unless translateKeywords is on with aiProvider=openai."
          },
          "openaiModel": {
            "title": "Translation model (OpenAI)",
            "type": "string",
            "description": "OpenAI model used for keyword translation when aiProvider is <code>openai</code> (only relevant when \"Translate keyword\" is on). Defaults to <code>gpt-4.1-mini</code> — cheap, fast and ample for this short translation task. Any chat-completions model works, including the gpt-5 family (e.g. <code>gpt-5.4-mini</code>).",
            "default": "gpt-4.1-mini"
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Proxy used to reach EURAXESS. Leave at the default: the Actor starts on the fast datacenter proxy and switches itself to residential only if the portal blocks it, which is much quicker than forcing residential up front. Pick explicit proxy groups here and the Actor uses exactly those, with no automatic fallback.",
            "default": {
              "useApifyProxy": true
            }
          },
          "requestTimeoutSecs": {
            "title": "Request timeout (seconds)",
            "minimum": 5,
            "maximum": 120,
            "type": "integer",
            "description": "How many seconds to wait for the EURAXESS website to answer before giving up on that page and moving on.",
            "default": 30
          },
          "cacheTtlSeconds": {
            "title": "Cache TTL (seconds)",
            "minimum": 0,
            "type": "integer",
            "description": "Reuse a page already fetched from EURAXESS for this many seconds instead of downloading it again on a quick re-run. Set to 0 to always fetch fresh.",
            "default": 1800
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}