# Donjons et raids

> Donjons et raids : niveaux, accès, rencontres dans l’ordre du jeu, quêtes et tout le butin par difficulté.

Documentation de l’API de WoWDB des Défias : https://docs.wowdb.assemblee-defias.fr/instances

## Donjons et raids

Les donjons et raids qui ont du butin. Leur identifiant est le **numéro de carte du jeu** (`36` : Mortemines, `631` : Citadelle de la Couronne de glace). Le butin se lit à plat, filtrable par rencontre, difficulté, qualité et filtre voleur.

**Routes**

- `GET /v1/{version}/instances` : Lister les donjons et raids
- `GET /v1/{version}/instances/{id}` : Obtenir un donjon ou raid
- `GET /v1/{version}/instances/{id}/loot` : Lister le butin d’un donjon

## L’objet instance

Un donjon ou un raid.

- `object` (chaîne) : Toujours « instance ». Valeurs : `instance`.
- `id` (entier) : Numéro de carte du jeu (36 : Mortemines).
- `key` (chaîne) : Clé WoWDB : « <version>:<carte> » (classic:36).
- `version` (code) : Version du jeu. Valeurs : `classic`, `tbc`, `wotlk`.
- `name` (chaîne) : Nom français.
- `icon` (chaîne ou null) : Adresse absolue de l’icône du jeu (WebP, JPEG ou PNG), servie par WoWDB ; null si la fiche n’en a pas.
- `type` (code) : Donjon ou raid. Valeurs : `dungeon`, `raid`.
- `type_name` (chaîne) : Libellé français.
- `level_min` (entier ou null) : Niveau conseillé minimum.
- `level_max` (entier ou null) : Niveau conseillé maximum.
- `required_level` (entier ou null) : Niveau requis pour entrer.
- `players` (entier ou null) : Nombre de joueurs.
- `bosses` (entier) : Nombre de boss.
- `items` (entier) : Nombre d’objets de butin.
- `rogue_items` (entier) : Objets utiles au voleur dans le butin.
- `url` (chaîne) : Page du donjon sur WoWDB.
- `api_url` (chaîne) : Adresse du donjon dans l’API.

Champs de la fiche seulement (`GET …/{id}`) :

- `modes` (tableau d’objets) : Modes de difficulté du jeu.
  - `name` (chaîne ou null) : Libellé (« 10 joueurs héroïque »).
  - `players` (entier ou null) : Joueurs.
- `difficulties` (tableau d’objets) : Difficultés qui ont du butin.
  - `difficulty` (code ou null) : Code. Valeurs : `normal`, `heroic`, `10_player`, `25_player`, `10_player_heroic`, `25_player_heroic`.
  - `difficulty_name` (chaîne ou null) : Libellé.
- `access` (tableau d’objets) : Conditions d’accès : clé, quête, haut fait.
  - `type` (chaîne) : item, quest ou achievement.
  - `heroic` (booléen) : Vrai pour le mode héroïque.
  - `name` (chaîne ou null) : Nom.
  - `item` (Ref ou null, facultatif) : La clé (type item).
  - `quest` (Ref ou null, facultatif) : La quête (type quest).
- `encounters` (tableau d’objets) : Rencontres, dans l’ordre du jeu quand il est connu.
  - `position` (entier) : Place dans le donjon (1 = première).
  - `name` (chaîne) : Nom de la rencontre.
  - `npc` (Ref ou null) : Fiche du boss.
  - `icon` (chaîne ou null) : Icône du boss.
  - `items` (entier) : Objets de butin.
  - `rogue_items` (entier) : Objets utiles au voleur.
  - `difficulties` (tableau de codes) : Difficultés où il a du butin. Valeurs : `normal`, `heroic`, `10_player`, `25_player`, `10_player_heroic`, `25_player_heroic`.
  - `loot_url` (chaîne) : Son butin : /instances/{id}/loot?encounter=<id du PNJ>.
- `game_order` (booléen) : Vrai si les rencontres suivent l’ordre du jeu (sinon : ordre alphabétique).
- `quests` (tableau d’objets) : Quêtes liées au donjon.
  - `quest` (Ref) : La quête.
  - `reason` (chaîne ou null) : Lien avec le donjon (« Quête du donjon »).
  - `level` (entier ou null) : Niveau.
- `loot_url` (chaîne) : Tout le butin : /instances/{id}/loot.
- `versions` (tableau de InstanceRef) : Le même donjon dans chaque version.
- `guides` (tableau d’objets) : Guides de L’Assemblée des Défias qui citent cette fiche.
  - `title` (chaîne) : Titre du guide.
  - `url` (chaîne) : Adresse du guide sur assemblee-defias.fr.

**Exemple : donjon ou raid** (statut 200)

```json
{
  "object": "instance",
  "id": 36,
  "key": "classic:36",
  "version": "classic",
  "name": "Mortemines",
  "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_map_01.webp",
  "type": "dungeon",
  "type_name": "Donjon",
  "level_min": 17,
  "level_max": 20,
  "required_level": 10,
  "players": 10,
  "bosses": 8,
  "items": 116,
  "rogue_items": 53,
  "url": "https://wowdb.assemblee-defias.fr/?instance=classic:36",
  "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36",
  "modes": [
    {
      "name": "Normal",
      "players": 10
    }
  ],
  "difficulties": [
    {
      "difficulty": "normal",
      "difficulty_name": "Normal"
    }
  ],
  "access": [],
  "encounters": [
    {
      "position": 1,
      "name": "Rhahk'Zor",
      "npc": {
        "object": "npc",
        "id": 644,
        "version": "classic",
        "name": "Rhahk'Zor",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:644",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/644"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 1,
      "rogue_items": 0,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=644"
    },
    {
      "position": 2,
      "name": "Sneed",
      "npc": {
        "object": "npc",
        "id": 643,
        "version": "classic",
        "name": "Sneed",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:643",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/643"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 3,
      "rogue_items": 0,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=643"
    },
    {
      "position": 3,
      "name": "Gilnid",
      "npc": {
        "object": "npc",
        "id": 1763,
        "version": "classic",
        "name": "Gilnid",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:1763",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/1763"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 2,
      "rogue_items": 2,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=1763"
    },
    {
      "position": 4,
      "name": "M. Châtiment",
      "npc": {
        "object": "npc",
        "id": 646,
        "version": "classic",
        "name": "M. Châtiment",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:646",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/646"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 3,
      "rogue_items": 1,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=646"
    },
    {
      "position": 5,
      "name": "Macaron",
      "npc": {
        "object": "npc",
        "id": 645,
        "version": "classic",
        "name": "Macaron",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:645",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/645"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 3,
      "rogue_items": 2,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=645"
    },
    {
      "position": 6,
      "name": "Capitaine Vertepeau",
      "npc": {
        "object": "npc",
        "id": 647,
        "version": "classic",
        "name": "Capitaine Vertepeau",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:647",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/647"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 3,
      "rogue_items": 1,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=647"
    },
    {
      "position": 7,
      "name": "Edwin VanCleef",
      "npc": {
        "object": "npc",
        "id": 639,
        "version": "classic",
        "name": "Edwin VanCleef",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:639",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/639"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/achievement_boss_edwinvancleef.webp",
      "items": 4,
      "rogue_items": 3,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=639"
    },
    {
      "position": 8,
      "name": "Mineur Johnson",
      "npc": {
        "object": "npc",
        "id": 3586,
        "version": "classic",
        "name": "Mineur Johnson",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:3586",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/3586"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 2,
      "rogue_items": 1,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=3586"
    }
  ],
  "game_order": true,
  "quests": [
    {
      "quest": {
        "object": "quest",
        "id": 214,
        "version": "classic",
        "name": "Les masques rouges en soie",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:214",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/214"
      },
      "reason": "Quête du donjon",
      "level": 17
    },
    {
      "quest": {
        "object": "quest",
        "id": 168,
        "version": "classic",
        "name": "À la recherche de cartes du syndicat des mineurs",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:168",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/168"
      },
      "reason": "Quête du donjon",
      "level": 18
    },
    {
      "quest": {
        "object": "quest",
        "id": 167,
        "version": "classic",
        "name": "Adieu mon frère…",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:167",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/167"
      },
      "reason": "Quête du donjon",
      "level": 20
    },
    {
      "quest": {
        "object": "quest",
        "id": 2040,
        "version": "classic",
        "name": "Assaut souterrain",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:2040",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/2040"
      },
      "reason": "Quête du donjon",
      "level": 20
    },
    {
      "quest": {
        "object": "quest",
        "id": 166,
        "version": "classic",
        "name": "La Confrérie défias",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:166",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/166"
      },
      "reason": "Quête du donjon",
      "level": 22
    },
    {
      "quest": {
        "object": "quest",
        "id": 373,
        "version": "classic",
        "name": "La lettre non envoyée",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:373",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/373"
      },
      "reason": "Objet à rapporter qui tombe dans le donjon",
      "level": 22
    },
    {
      "quest": {
        "object": "quest",
        "id": 1654,
        "version": "classic",
        "name": "Le test de droiture",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:1654",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/1654"
      },
      "reason": "Objet à rapporter qui tombe dans le donjon",
      "level": 22
    },
    {
      "quest": {
        "object": "quest",
        "id": 7938,
        "version": "classic",
        "name": "Une surprise vous attend...",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:7938",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/7938"
      },
      "reason": "Quête rendue dans le donjon",
      "level": 60
    }
  ],
  "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot",
  "versions": [
    {
      "object": "instance",
      "id": 36,
      "version": "classic",
      "name": "Mortemines",
      "type": "dungeon",
      "url": "https://wowdb.assemblee-defias.fr/?instance=classic:36",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36"
    },
    {
      "object": "instance",
      "id": 36,
      "version": "tbc",
      "name": "Mortemines",
      "type": "dungeon",
      "url": "https://wowdb.assemblee-defias.fr/?instance=tbc:36",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/tbc/instances/36"
    },
    {
      "object": "instance",
      "id": 36,
      "version": "wotlk",
      "name": "Mortemines",
      "type": "dungeon",
      "url": "https://wowdb.assemblee-defias.fr/?instance=wotlk:36",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/wotlk/instances/36"
    }
  ],
  "guides": []
}
```

## L’objet loot de donjon

Une ligne du butin d’un donjon : un objet, une source, une difficulté.

- `object` (chaîne) : Toujours « loot ». Valeurs : `loot`.
- `item` (ItemRef) : L’objet.
- `name` (chaîne) : Nom.
- `chance` (nombre ou null) : Chance en pour cent.
- `difficulty` (code ou null) : Difficulté. Valeurs : `normal`, `heroic`, `10_player`, `25_player`, `10_player_heroic`, `25_player_heroic`.
- `difficulty_name` (chaîne ou null) : Libellé.
- `rogue` (booléen) : Utile au voleur.
- `source` (objet) : Qui le lâche.
  - `kind` (chaîne) : encounter (boss), chest (coffre) ou npc (autre monstre).
  - `name` (chaîne) : Nom.
  - `boss` (booléen) : Vrai pour un boss.
  - `npc` (Ref ou null) : Fiche du PNJ.
  - `npc_ids` (tableau de entiers) : Identifiants du PNJ dans chaque difficulté (filtre encounter).

## Lister les donjons et raids

`GET /v1/{version}/instances`

Les donjons puis les raids d’une version qui ont du butin, par nom. Identifiant : numéro de carte du jeu.

**Paramètres**

- `version` (code, dans le chemin, obligatoire) : Version du jeu : classic (Vanilla 1.12.1), tbc (2.4.3) ou wotlk (3.3.5a). Valeurs : `classic`, `tbc`, `wotlk`.
- `type` (codes séparés par des virgules, facultatif) : Donjon ou raid. Plusieurs valeurs séparées par des virgules. Valeurs : `dungeon`, `raid`.
- `rogue` (booléen, facultatif) : true : seulement les donjons qui ont du butin utiles au voleur ; false : seulement les autres. Absent : tout (par défaut).
- `limit` (entier, facultatif) : Nombre d’éléments par page, de 1 à 100 (20 par défaut).
- `cursor` (chaîne, facultatif) : Curseur de la page suivante : la valeur de next_cursor de la page précédente, avec les mêmes filtres.
- `include_total` (booléen, facultatif) : true : ajoute total_count, le nombre total d’éléments avec ces filtres.

**Renvoie** : Une liste (`object: "list"`) d’objets `instance`, paginée par curseur.

**Requête (GET /v1/{version}/instances)**

#### cURL

```bash
curl -G https://api.wowdb.assemblee-defias.fr/v1/classic/instances \
  -d type=dungeon \
  -d limit=2
```

#### JavaScript

```js
const params = new URLSearchParams({
  type: "dungeon",
  limit: "2",
});
const res = await fetch(`https://api.wowdb.assemblee-defias.fr/v1/classic/instances?${params}`);
if (!res.ok) throw new Error((await res.json()).error.message);
const page = await res.json();
for (const instance of page.data) {
  console.log(instance.name);
}
```

#### Python

```python
import json
import urllib.parse
import urllib.request

params = urllib.parse.urlencode({
    "type": "dungeon",
    "limit": "2",
})
req = urllib.request.Request(
    f"https://api.wowdb.assemblee-defias.fr/v1/classic/instances?{params}",
    headers={"User-Agent": "mon-application/1.0 (contact@example.com)"},
)
with urllib.request.urlopen(req) as res:
    page = json.load(res)
for instance in page["data"]:
    print(instance["name"])
```

#### PHP

```php
<?php
$params = http_build_query([
    'type' => 'dungeon',
    'limit' => '2',
]);
$context = stream_context_create([
    'http' => ['header' => "User-Agent: mon-application/1.0 (contact@example.com)\r\n"],
]);
$json = file_get_contents('https://api.wowdb.assemblee-defias.fr/v1/classic/instances?' . $params, false, $context);
$page = json_decode($json, true);
foreach ($page['data'] as $instance) {
    echo $instance['name'], PHP_EOL;
}
```

#### Ruby

```ruby
require "json"
require "net/http"

uri = URI("https://api.wowdb.assemblee-defias.fr/v1/classic/instances")
uri.query = URI.encode_www_form(
  type: "dungeon",
  limit: "2",
)
res = Net::HTTP.get_response(uri, { "User-Agent" => "mon-application/1.0 (contact@example.com)" })
page = JSON.parse(res.body)
page["data"].each do |instance|
  puts instance["name"]
end
```

#### Go

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
)

func main() {
	params := url.Values{}
	params.Set("type", "dungeon")
	params.Set("limit", "2")
	req, err := http.NewRequest("GET", "https://api.wowdb.assemblee-defias.fr/v1/classic/instances?"+params.Encode(), nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("User-Agent", "mon-application/1.0 (contact@example.com)")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	var page struct {
		Data    []map[string]any `json:"data"`
		HasMore bool             `json:"has_more"`
	}
	if err := json.NewDecoder(res.Body).Decode(&page); err != nil {
		panic(err)
	}
	for _, instance := range page.Data {
		fmt.Println(instance["name"])
	}
}
```

#### Java

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Exemple {
    public static void main(String[] args) throws Exception {
        HttpRequest request = HttpRequest.newBuilder(URI.create(
                "https://api.wowdb.assemblee-defias.fr/v1/classic/instances?type=dungeon&limit=2"))
            .header("User-Agent", "mon-application/1.0 (contact@example.com)")
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());
        // JSON à lire avec Jackson, Gson ou le client WowDb.java (sans dépendance)
        System.out.println(response.body());
    }
}
```

#### .NET

```csharp
using System.Net.Http;
using System.Text.Json;

using var http = new HttpClient();
http.DefaultRequestHeaders.UserAgent.ParseAdd("mon-application/1.0 (contact@example.com)");
var json = await http.GetStringAsync(
    "https://api.wowdb.assemblee-defias.fr/v1/classic/instances?type=dungeon&limit=2");
using var doc = JsonDocument.Parse(json);
foreach (var instance in doc.RootElement.GetProperty("data").EnumerateArray())
    Console.WriteLine(instance.GetProperty("name").GetString());
```

#### Rust

```rust
// Cargo.toml : ureq = { version = "2", features = ["json"] } et serde_json = "1"
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let page: serde_json::Value = ureq::get("https://api.wowdb.assemblee-defias.fr/v1/classic/instances")
        .set("User-Agent", "mon-application/1.0 (contact@example.com)")
        .query("type", "dungeon")
        .query("limit", "2")
        .call()?
        .into_json()?;
    for instance in page["data"].as_array().into_iter().flatten() {
        println!("{}", instance["name"].as_str().unwrap_or_default());
    }
    Ok(())
}
```

**Réponse** (statut 200)

```json
{
  "object": "list",
  "data": [
    {
      "object": "instance",
      "id": 43,
      "key": "classic:43",
      "version": "classic",
      "name": "Cavernes des Lamentations",
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_map_01.webp",
      "type": "dungeon",
      "type_name": "Donjon",
      "level_min": 17,
      "level_max": 20,
      "required_level": 10,
      "players": 10,
      "bosses": 9,
      "items": 109,
      "rogue_items": 44,
      "url": "https://wowdb.assemblee-defias.fr/?instance=classic:43",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/43"
    },
    {
      "object": "instance",
      "id": 33,
      "key": "classic:33",
      "version": "classic",
      "name": "Donjon d'Ombrecroc",
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_map_01.webp",
      "type": "dungeon",
      "type_name": "Donjon",
      "level_min": 18,
      "level_max": 21,
      "required_level": 10,
      "players": 10,
      "bosses": 9,
      "items": 22,
      "rogue_items": 8,
      "url": "https://wowdb.assemblee-defias.fr/?instance=classic:33",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/33"
    }
  ],
  "has_more": true,
  "next_cursor": "eyJvIjoyLCJoIjoiajQ0b1hrdy1BMyJ9",
  "url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances?type=dungeon"
}
```

## Obtenir un donjon ou raid

`GET /v1/{version}/instances/{id}`

La fiche complète du donjon : les champs de la liste, plus ceux marqués « fiche seulement ».

**Paramètres**

- `version` (code, dans le chemin, obligatoire) : Version du jeu : classic (Vanilla 1.12.1), tbc (2.4.3) ou wotlk (3.3.5a). Valeurs : `classic`, `tbc`, `wotlk`.
- `id` (entier, dans le chemin, obligatoire) : Identifiant du jeu du donjon.

**Renvoie** : La fiche complète, objet `instance` (champs du résumé et champs « fiche seulement »), ou une erreur 404.

**Requête (GET /v1/{version}/instances/{id})**

#### cURL

```bash
curl https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36
```

#### JavaScript

```js
const res = await fetch("https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36");
if (!res.ok) throw new Error((await res.json()).error.message);
const instance = await res.json();
console.log(instance.name);
```

#### Python

```python
import json
import urllib.request

req = urllib.request.Request(
    "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36",
    headers={"User-Agent": "mon-application/1.0 (contact@example.com)"},
)
with urllib.request.urlopen(req) as res:
    instance = json.load(res)
print(instance["name"])
```

#### PHP

```php
<?php
$context = stream_context_create([
    'http' => ['header' => "User-Agent: mon-application/1.0 (contact@example.com)\r\n"],
]);
$json = file_get_contents('https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36', false, $context);
$instance = json_decode($json, true);
echo $instance['name'], PHP_EOL;
```

#### Ruby

```ruby
require "json"
require "net/http"

uri = URI("https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36")
res = Net::HTTP.get_response(uri, { "User-Agent" => "mon-application/1.0 (contact@example.com)" })
instance = JSON.parse(res.body)
puts instance["name"]
```

#### Go

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

func main() {
	req, err := http.NewRequest("GET", "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36", nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("User-Agent", "mon-application/1.0 (contact@example.com)")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	var instance map[string]any
	if err := json.NewDecoder(res.Body).Decode(&instance); err != nil {
		panic(err)
	}
	fmt.Println(instance["name"])
}
```

#### Java

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Exemple {
    public static void main(String[] args) throws Exception {
        HttpRequest request = HttpRequest.newBuilder(URI.create(
                "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36"))
            .header("User-Agent", "mon-application/1.0 (contact@example.com)")
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());
        // JSON à lire avec Jackson, Gson ou le client WowDb.java (sans dépendance)
        System.out.println(response.body());
    }
}
```

#### .NET

```csharp
using System.Net.Http;
using System.Text.Json;

using var http = new HttpClient();
http.DefaultRequestHeaders.UserAgent.ParseAdd("mon-application/1.0 (contact@example.com)");
var json = await http.GetStringAsync(
    "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36");
using var doc = JsonDocument.Parse(json);
Console.WriteLine(doc.RootElement.GetProperty("name").GetString());
```

#### Rust

```rust
// Cargo.toml : ureq = { version = "2", features = ["json"] } et serde_json = "1"
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let instance: serde_json::Value = ureq::get("https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36")
        .set("User-Agent", "mon-application/1.0 (contact@example.com)")
        .call()?
        .into_json()?;
    println!("{}", instance["name"].as_str().unwrap_or_default());
    Ok(())
}
```

**Réponse** (statut 200)

```json
{
  "object": "instance",
  "id": 36,
  "key": "classic:36",
  "version": "classic",
  "name": "Mortemines",
  "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_map_01.webp",
  "type": "dungeon",
  "type_name": "Donjon",
  "level_min": 17,
  "level_max": 20,
  "required_level": 10,
  "players": 10,
  "bosses": 8,
  "items": 116,
  "rogue_items": 53,
  "url": "https://wowdb.assemblee-defias.fr/?instance=classic:36",
  "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36",
  "modes": [
    {
      "name": "Normal",
      "players": 10
    }
  ],
  "difficulties": [
    {
      "difficulty": "normal",
      "difficulty_name": "Normal"
    }
  ],
  "access": [],
  "encounters": [
    {
      "position": 1,
      "name": "Rhahk'Zor",
      "npc": {
        "object": "npc",
        "id": 644,
        "version": "classic",
        "name": "Rhahk'Zor",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:644",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/644"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 1,
      "rogue_items": 0,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=644"
    },
    {
      "position": 2,
      "name": "Sneed",
      "npc": {
        "object": "npc",
        "id": 643,
        "version": "classic",
        "name": "Sneed",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:643",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/643"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 3,
      "rogue_items": 0,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=643"
    },
    {
      "position": 3,
      "name": "Gilnid",
      "npc": {
        "object": "npc",
        "id": 1763,
        "version": "classic",
        "name": "Gilnid",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:1763",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/1763"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 2,
      "rogue_items": 2,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=1763"
    },
    {
      "position": 4,
      "name": "M. Châtiment",
      "npc": {
        "object": "npc",
        "id": 646,
        "version": "classic",
        "name": "M. Châtiment",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:646",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/646"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 3,
      "rogue_items": 1,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=646"
    },
    {
      "position": 5,
      "name": "Macaron",
      "npc": {
        "object": "npc",
        "id": 645,
        "version": "classic",
        "name": "Macaron",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:645",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/645"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 3,
      "rogue_items": 2,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=645"
    },
    {
      "position": 6,
      "name": "Capitaine Vertepeau",
      "npc": {
        "object": "npc",
        "id": 647,
        "version": "classic",
        "name": "Capitaine Vertepeau",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:647",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/647"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 3,
      "rogue_items": 1,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=647"
    },
    {
      "position": 7,
      "name": "Edwin VanCleef",
      "npc": {
        "object": "npc",
        "id": 639,
        "version": "classic",
        "name": "Edwin VanCleef",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:639",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/639"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/achievement_boss_edwinvancleef.webp",
      "items": 4,
      "rogue_items": 3,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=639"
    },
    {
      "position": 8,
      "name": "Mineur Johnson",
      "npc": {
        "object": "npc",
        "id": 3586,
        "version": "classic",
        "name": "Mineur Johnson",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:3586",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/3586"
      },
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_bone_orcskull_01.webp",
      "items": 2,
      "rogue_items": 1,
      "difficulties": [
        "normal"
      ],
      "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=3586"
    }
  ],
  "game_order": true,
  "quests": [
    {
      "quest": {
        "object": "quest",
        "id": 214,
        "version": "classic",
        "name": "Les masques rouges en soie",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:214",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/214"
      },
      "reason": "Quête du donjon",
      "level": 17
    },
    {
      "quest": {
        "object": "quest",
        "id": 168,
        "version": "classic",
        "name": "À la recherche de cartes du syndicat des mineurs",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:168",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/168"
      },
      "reason": "Quête du donjon",
      "level": 18
    },
    {
      "quest": {
        "object": "quest",
        "id": 167,
        "version": "classic",
        "name": "Adieu mon frère…",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:167",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/167"
      },
      "reason": "Quête du donjon",
      "level": 20
    },
    {
      "quest": {
        "object": "quest",
        "id": 2040,
        "version": "classic",
        "name": "Assaut souterrain",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:2040",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/2040"
      },
      "reason": "Quête du donjon",
      "level": 20
    },
    {
      "quest": {
        "object": "quest",
        "id": 166,
        "version": "classic",
        "name": "La Confrérie défias",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:166",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/166"
      },
      "reason": "Quête du donjon",
      "level": 22
    },
    {
      "quest": {
        "object": "quest",
        "id": 373,
        "version": "classic",
        "name": "La lettre non envoyée",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:373",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/373"
      },
      "reason": "Objet à rapporter qui tombe dans le donjon",
      "level": 22
    },
    {
      "quest": {
        "object": "quest",
        "id": 1654,
        "version": "classic",
        "name": "Le test de droiture",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:1654",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/1654"
      },
      "reason": "Objet à rapporter qui tombe dans le donjon",
      "level": 22
    },
    {
      "quest": {
        "object": "quest",
        "id": 7938,
        "version": "classic",
        "name": "Une surprise vous attend...",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:7938",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/7938"
      },
      "reason": "Quête rendue dans le donjon",
      "level": 60
    }
  ],
  "loot_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot",
  "versions": [
    {
      "object": "instance",
      "id": 36,
      "version": "classic",
      "name": "Mortemines",
      "type": "dungeon",
      "url": "https://wowdb.assemblee-defias.fr/?instance=classic:36",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36"
    },
    {
      "object": "instance",
      "id": 36,
      "version": "tbc",
      "name": "Mortemines",
      "type": "dungeon",
      "url": "https://wowdb.assemblee-defias.fr/?instance=tbc:36",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/tbc/instances/36"
    },
    {
      "object": "instance",
      "id": 36,
      "version": "wotlk",
      "name": "Mortemines",
      "type": "dungeon",
      "url": "https://wowdb.assemblee-defias.fr/?instance=wotlk:36",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/wotlk/instances/36"
    }
  ],
  "guides": []
}
```

## Lister le butin d’un donjon

`GET /v1/{version}/instances/{id}/loot`

Tout le butin du donjon ou du raid : une ligne par objet, source et difficulté, rencontres d’abord, dans l’ordre du jeu.

Exemple : le butin d’Edwin VanCleef utile au voleur.

**Paramètres**

- `version` (code, dans le chemin, obligatoire) : Version du jeu : classic (Vanilla 1.12.1), tbc (2.4.3) ou wotlk (3.3.5a). Valeurs : `classic`, `tbc`, `wotlk`.
- `id` (entier, dans le chemin, obligatoire) : Identifiant du jeu du donjon (numéro de carte).
- `encounter` (entier, facultatif) : Identifiant du PNJ d’une rencontre (encounters[].npc.id ou une de ses variantes) : son butin seulement.
- `difficulty` (codes séparés par des virgules, facultatif) : Difficultés. Valeurs : `normal`, `heroic`, `10_player`, `25_player`, `10_player_heroic`, `25_player_heroic`.
- `quality` (codes séparés par des virgules, facultatif) : Qualités. Valeurs : `poor`, `common`, `uncommon`, `rare`, `epic`, `legendary`, `artifact`, `heirloom`.
- `rogue` (booléen, facultatif) : true : seulement les objets utiles au voleur ; false : seulement les autres. Absent : tout (par défaut).
- `limit` (entier, facultatif) : Nombre d’éléments par page, de 1 à 100 (20 par défaut).
- `cursor` (chaîne, facultatif) : Curseur de la page suivante : la valeur de next_cursor de la page précédente, avec les mêmes filtres.
- `include_total` (booléen, facultatif) : true : ajoute total_count, le nombre total d’éléments avec ces filtres.

**Renvoie** : Une liste (`object: "list"`) d’objets `loot`, paginée par curseur.

**Requête (GET /v1/{version}/instances/{id}/loot)**

#### cURL

```bash
curl -G https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot \
  -d encounter=639 \
  -d rogue=true \
  -d limit=2
```

#### JavaScript

```js
const params = new URLSearchParams({
  encounter: "639",
  rogue: "true",
  limit: "2",
});
const res = await fetch(`https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?${params}`);
if (!res.ok) throw new Error((await res.json()).error.message);
const page = await res.json();
for (const loot of page.data) {
  console.log(loot.name);
}
```

#### Python

```python
import json
import urllib.parse
import urllib.request

params = urllib.parse.urlencode({
    "encounter": "639",
    "rogue": "true",
    "limit": "2",
})
req = urllib.request.Request(
    f"https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?{params}",
    headers={"User-Agent": "mon-application/1.0 (contact@example.com)"},
)
with urllib.request.urlopen(req) as res:
    page = json.load(res)
for loot in page["data"]:
    print(loot["name"])
```

#### PHP

```php
<?php
$params = http_build_query([
    'encounter' => '639',
    'rogue' => 'true',
    'limit' => '2',
]);
$context = stream_context_create([
    'http' => ['header' => "User-Agent: mon-application/1.0 (contact@example.com)\r\n"],
]);
$json = file_get_contents('https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?' . $params, false, $context);
$page = json_decode($json, true);
foreach ($page['data'] as $loot) {
    echo $loot['name'], PHP_EOL;
}
```

#### Ruby

```ruby
require "json"
require "net/http"

uri = URI("https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot")
uri.query = URI.encode_www_form(
  encounter: "639",
  rogue: "true",
  limit: "2",
)
res = Net::HTTP.get_response(uri, { "User-Agent" => "mon-application/1.0 (contact@example.com)" })
page = JSON.parse(res.body)
page["data"].each do |loot|
  puts loot["name"]
end
```

#### Go

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
)

func main() {
	params := url.Values{}
	params.Set("encounter", "639")
	params.Set("rogue", "true")
	params.Set("limit", "2")
	req, err := http.NewRequest("GET", "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?"+params.Encode(), nil)
	if err != nil {
		panic(err)
	}
	req.Header.Set("User-Agent", "mon-application/1.0 (contact@example.com)")
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		panic(err)
	}
	defer res.Body.Close()
	var page struct {
		Data    []map[string]any `json:"data"`
		HasMore bool             `json:"has_more"`
	}
	if err := json.NewDecoder(res.Body).Decode(&page); err != nil {
		panic(err)
	}
	for _, loot := range page.Data {
		fmt.Println(loot["name"])
	}
}
```

#### Java

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Exemple {
    public static void main(String[] args) throws Exception {
        HttpRequest request = HttpRequest.newBuilder(URI.create(
                "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=639&rogue=true&limit=2"))
            .header("User-Agent", "mon-application/1.0 (contact@example.com)")
            .build();
        HttpResponse<String> response = HttpClient.newHttpClient()
            .send(request, HttpResponse.BodyHandlers.ofString());
        // JSON à lire avec Jackson, Gson ou le client WowDb.java (sans dépendance)
        System.out.println(response.body());
    }
}
```

#### .NET

```csharp
using System.Net.Http;
using System.Text.Json;

using var http = new HttpClient();
http.DefaultRequestHeaders.UserAgent.ParseAdd("mon-application/1.0 (contact@example.com)");
var json = await http.GetStringAsync(
    "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=639&rogue=true&limit=2");
using var doc = JsonDocument.Parse(json);
foreach (var loot in doc.RootElement.GetProperty("data").EnumerateArray())
    Console.WriteLine(loot.GetProperty("name").GetString());
```

#### Rust

```rust
// Cargo.toml : ureq = { version = "2", features = ["json"] } et serde_json = "1"
fn main() -> Result<(), Box<dyn std::error::Error>> {
    let page: serde_json::Value = ureq::get("https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot")
        .set("User-Agent", "mon-application/1.0 (contact@example.com)")
        .query("encounter", "639")
        .query("rogue", "true")
        .query("limit", "2")
        .call()?
        .into_json()?;
    for loot in page["data"].as_array().into_iter().flatten() {
        println!("{}", loot["name"].as_str().unwrap_or_default());
    }
    Ok(())
}
```

**Réponse** (statut 200)

```json
{
  "object": "list",
  "data": [
    {
      "object": "loot",
      "item": {
        "object": "item",
        "id": 5193,
        "version": "classic",
        "name": "Cape de la confrérie",
        "quality": "rare",
        "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_cape_08.jpg",
        "item_level": 25,
        "slot_name": "Dos",
        "type_name": "Tissu",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:5193",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/5193"
      },
      "name": "Cape de la confrérie",
      "chance": 30,
      "difficulty": "normal",
      "difficulty_name": "Normal",
      "rogue": true,
      "source": {
        "kind": "encounter",
        "name": "Edwin VanCleef",
        "boss": true,
        "npc": {
          "object": "npc",
          "id": 639,
          "version": "classic",
          "name": "Edwin VanCleef",
          "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:639",
          "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/639"
        },
        "npc_ids": [
          639
        ]
      }
    },
    {
      "object": "loot",
      "item": {
        "object": "item",
        "id": 10399,
        "version": "classic",
        "name": "Armure défias noircie",
        "quality": "rare",
        "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_chest_leather_08.jpg",
        "item_level": 24,
        "slot_name": "Torse",
        "type_name": "Cuir",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:10399",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/10399"
      },
      "name": "Armure défias noircie",
      "chance": 20,
      "difficulty": "normal",
      "difficulty_name": "Normal",
      "rogue": true,
      "source": {
        "kind": "encounter",
        "name": "Edwin VanCleef",
        "boss": true,
        "npc": {
          "object": "npc",
          "id": 639,
          "version": "classic",
          "name": "Edwin VanCleef",
          "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:639",
          "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/639"
        },
        "npc_ids": [
          639
        ]
      }
    }
  ],
  "has_more": true,
  "next_cursor": "eyJvIjoyLCJoIjoiRFllWTV5OE0yYiJ9",
  "url": "https://api.wowdb.assemblee-defias.fr/v1/classic/instances/36/loot?encounter=639&rogue=true"
}
```

---

API de WoWDB des Défias, v1 (2026-10-01). Adresse de base : https://api.wowdb.assemblee-defias.fr/v1. Index : https://docs.wowdb.assemblee-defias.fr/llms.txt.
