# tarkov.dev GraphQL API Reference

> Community-made, real-time EFT data. No API key required.

- **Endpoint:** `https://api.tarkov.dev/graphql`
- **Playground:** `https://api.tarkov.dev/` (interactive explorer with autocomplete)
- **Protocol:** GraphQL over HTTP POST
- **Auth:** None — completely open
- **Source:** https://github.com/the-hideout/tarkov-api

---

## How to query (Python)

```python
import requests

API_URL = "https://api.tarkov.dev/graphql"

def gql(query):
    r = requests.post(API_URL, json={"query": query})
    r.raise_for_status()
    data = r.json()
    if "errors" in data:
        raise RuntimeError(data["errors"])
    return data["data"]
```

---

## Common arguments (most queries accept these)

| Arg        | Type           | Notes                                      |
|------------|----------------|--------------------------------------------|
| `lang`     | `LanguageCode` | e.g. `en`, `ru`, `de`, `fr`, `es`, `zh`   |
| `gameMode` | `GameMode`     | `regular` or `pve`                         |
| `limit`    | `Int`          | Max results to return                      |
| `offset`   | `Int`          | Pagination offset                          |

---

## All available root queries

```
achievements(lang, limit, offset)
ammo(lang, gameMode, limit, offset)
archivedItemPrices(id, limit, offset)
barters(lang, gameMode, limit, offset)
bosses(lang, gameMode, name, limit, offset)
crafts(lang, gameMode, limit, offset)
fleaMarket(lang, gameMode)
goonReports(lang, gameMode, limit, offset)
handbookCategories(lang, limit, offset)
hideoutStations(lang, gameMode, limit, offset)
historicalItemPrices(id, days, lang, gameMode, limit, offset)
item(id, normalizedName, lang, gameMode)
items(ids, name, names, type, types, categoryNames, handbookCategoryNames, bsgCategoryId, bsgCategoryIds, bsgCategory, lang, gameMode, limit, offset)
itemCategories(lang, limit, offset)
itemPrices(id, gameMode, limit, offset)
lootContainers(lang, limit, offset)
maps(lang, gameMode, name, enemies, limit, offset)
mastering(lang)
playerLevels()
prestige(lang, gameMode)
questItems(lang)
skills(lang)
stationaryWeapons(lang, limit, offset)
status()
task(id, lang, gameMode)
tasks(faction, lang, gameMode, limit, offset)
traders(lang, gameMode, limit, offset)
```

---

## Query examples

### Server status
```graphql
{
  status {
    currentStatuses {
      name
      message
      status
    }
    messages {
      time
      type
      content
      solveTime
    }
  }
}
```

### Single item by name
```graphql
{
  items(name: "colt m4a1") {
    id
    name
    shortName
    basePrice
    avg24hPrice
    changeLast48hPercent
    width
    height
    weight
    wikiLink
    iconLink
    gridImageLink
    sellFor {
      price
      currency
      source
    }
    buyFor {
      price
      currency
      source
    }
  }
}
```

### Items by type (e.g. all keys)
```graphql
{
  items(types: [keys]) {
    id
    name
    shortName
    wikiLink
    gridImageLink
    properties {
      ... on ItemPropertiesKey {
        uses
      }
    }
  }
}
```

Valid `ItemType` values include: `keys`, `ammo`, `armor`, `backpack`, `gun`, `headwear`, `rig`, `medical`, `food`, `barter`, `container`, `grenade`, `headphones`, `knife`, `stimulator`, `suppressor`, `weapon`

### All tasks / quests
```graphql
{
  tasks {
    id
    name
    wikiLink
    minPlayerLevel
    kappaRequired
    trader {
      name
    }
    taskRequirements {
      task {
        id
        name
      }
      status
    }
    objectives {
      id
      type
      description
      maps {
        name
        normalizedName
      }
      ... on TaskObjectiveItem {
        item { name shortName }
        count
        foundInRaid
      }
      ... on TaskObjectiveShoot {
        targetNames
        count
      }
      ... on TaskObjectiveLocation {
        locationNames
      }
      ... on TaskObjectiveQuestItem {
        questItem { name }
        count
      }
      ... on TaskObjectiveSkill {
        skillLevel { name level }
      }
      ... on TaskObjectiveTraderLevel {
        trader { name }
        level
      }
    }
    startRewards {
      items { item { name } count }
      traderStanding { trader { name } standing }
    }
    finishRewards {
      items { item { name } count }
      experience
      traderStanding { trader { name } standing }
      offerUnlock { trader { name } item { name } }
    }
  }
}
```

> **Note:** `objectives` returns a `TaskObjective` **interface** — use inline fragments (`... on TypeName`) to access type-specific fields.

### Single task by ID
```graphql
{
  task(id: "5936d90786f7742b1420ba5b") {
    name
    trader { name }
    taskRequirements { task { id name } }
  }
}
```

### Ammo stats
```graphql
{
  ammo {
    item { name shortName }
    caliber
    damage
    armorDamage
    penetrationPower
    penetrationChance
    fragmentationChance
    initialSpeed
    lightBleedModifier
    heavyBleedModifier
  }
}
```

### Traders
```graphql
{
  traders {
    id
    name
    normalizedName
    currency { name }
    levels {
      level
      requiredPlayerLevel
      requiredReputation
      requiredCommerce
      cashOffers {
        item { name }
        price
        currency
        minTraderLevel
        taskUnlock { name }
      }
    }
    barters {
      requiredItems { item { name } count }
      rewardItems { item { name } count }
      minTraderLevel
      taskUnlock { name }
    }
  }
}
```

### Hideout stations
```graphql
{
  hideoutStations {
    id
    name
    levels {
      level
      constructionTime
      itemRequirements { item { name } count }
      stationLevelRequirements { station { name } level }
      skillRequirements { skill { name } level }
      traderRequirements { trader { name } requirementType value }
      bonuses { type value }
    }
  }
}
```

### Maps
```graphql
{
  maps {
    id
    name
    normalizedName
    raidDuration
    players
    bosses {
      boss { name }
      spawnChance
      spawnLocations { name chance }
      escorts { boss { name } amount { count chance } }
    }
    extracts {
      name
      faction
      switches { name }
    }
  }
}
```

### Crafts
```graphql
{
  crafts {
    station { name }
    level
    duration
    requiredItems { item { name } count }
    rewardItems { item { name } count }
    taskUnlock { name }
  }
}
```

### Barters
```graphql
{
  barters {
    trader { name }
    level
    taskUnlock { name }
    requiredItems { item { name } count }
    rewardItems { item { name } count }
  }
}
```

### Flea market info
```graphql
{
  fleaMarket {
    enabled
    minPlayerLevel
    sellOfferFeeRate
    sellRequirementFeeRate
  }
}
```

### Achievements
```graphql
{
  achievements {
    id
    name
    description
    hidden
    rarity
    playersCompletedPercent
    side
  }
}
```

### Goon reports (roaming boss locations)
```graphql
{
  goonReports {
    map { name }
    timestamp
  }
}
```

---

## Key types reference

### Item fields
```
id, name, shortName, normalizedName
basePrice, avg24hPrice, low24hPrice, high24hPrice
changeLast48h, changeLast48hPercent
lastLowPrice, lastOfferCount
width, height, weight, velocity
wikiLink, iconLink, gridImageLink, inspectImageLink, image8xLink
types[]           – ItemType enum values this item belongs to
sellFor[]         – { price, currency, source, vendor { name } }
buyFor[]          – { price, currency, source, vendor { name } }
bartersFor[]      – Barter objects
bartersUsing[]    – Barter objects
usedInTasks[]     – Task objects
receivedFromTasks[] – Task objects
properties        – ItemProperties union (see below)
category          – { id, name }
```

### ItemProperties union types
Use `... on ItemPropertiesX { }` inline fragments:
- `ItemPropertiesKey` → `uses`
- `ItemPropertiesAmmo` → `caliber, damage, penetrationPower, ...`
- `ItemPropertiesArmor` → `class, durability, material, zones[]`
- `ItemPropertiesArmorAttachment` → `class, durability, material, zones[], headCoverage`
- `ItemPropertiesBackpack` → `capacity, grids[]`
- `ItemPropertiesChestRig` → `capacity, class, durability, zones[]`
- `ItemPropertiesWeapon` → `caliber, fireRate, ergonomics, recoil...`
- `ItemPropertiesMagazine` → `capacity, caliber, ergonomics`
- `ItemPropertiesScope` → `ergonomics, recoil, zoomLevels[]`
- `ItemPropertiesMedKit` → `uses, useTime, hpCostLightBleeding, hpCostHeavyBleeding`
- `ItemPropertiesFood` → `energy, hydration, stimEffects[]`
- `ItemPropertiesStimulator` → `stimEffects[]`
- `ItemPropertiesHelmet` → `class, durability, material, headZones[], deafening`
- `ItemPropertiesGlasses` → `class, durability, blindnessProtection`
- `ItemPropertiesNightVision` → `intensity, noiseIntensity, noiseScale`
- `ItemPropertiesContainer` → `capacity`
- `ItemPropertiesGrenade` → `type, fuse, fragments, minExplosionDistance, maxExplosionDistance`

### Task / quest fields
```
id, name, normalizedName
wikiLink
minPlayerLevel
kappaRequired         – bool, whether needed for Kappa (The Collector)
restartable
trader { id, name }
map { id, name }      – nullable, map-specific tasks only
experience
taskRequirements[]    – { task { id, name }, status[] }
objectives[]          – TaskObjective interface (use inline fragments)
startRewards          – TaskRewards
finishRewards         – TaskRewards
```

### TaskRewards fields
```
items[]            – { item { name }, count }
traderStanding[]   – { trader { name }, standing }
offerUnlock[]      – { trader { name }, level, item { name } }
skillLevelReward[] – { name, level }
craftUnlock[]      – craft objects
```

---

## How we use it in this project

| Script | Query | Purpose |
|---|---|---|
| [import_keys.py](import_keys.py) | `items(types: [keys])` | Fetches all key items into `keys` table |
| [import_quests.py](import_quests.py) | `tasks { id name wikiLink trader taskRequirements }` | Fetches all tasks and their dependencies into `quests` + `quest_deps` tables |

The Collector prerequisite tree is computed from `quest_deps` using a recursive SQL CTE in [app.py](app.py) at `/collector`.
