# Quêtes

> Les 19 713 quêtes : objectifs, récompenses, PNJ de début et de fin, chaînes, catégories.

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

## Quêtes

Toutes les quêtes du jeu, avec leurs textes français, leurs objectifs, leurs récompenses et leur chaîne. Exemple : **La Confrérie défias** (`166`), la quête qui envoie tuer Edwin VanCleef.

**Routes**

- `GET /v1/{version}/quests` : Lister les quêtes
- `GET /v1/{version}/quests/{id}` : Obtenir une quête

## L’objet quest

Une quête. Les listes renvoient un résumé (niveau, camp, catégorie, récompenses) ; la fiche ajoute les textes, les objectifs, les récompenses détaillées, les PNJ et la chaîne.

- `object` (chaîne) : Type d’objet, toujours « quest ». Valeurs : `quest`.
- `id` (entier) : Identifiant de la quête : son numéro dans le jeu (entrée de la base du jeu), le même dans les trois versions quand la quête y existe.
- `key` (chaîne) : Clé WoWDB, unique dans toute la base : « <version>:<type>:<id> » (classic:quest:166).
- `version` (code) : Version du jeu de cette fiche. Valeurs : `classic`, `tbc`, `wotlk`.
- `name` (chaîne) : Nom français, comme en jeu.
- `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.
- `level` (entier ou null) : Niveau de la quête.
- `required_level` (entier ou null) : Niveau requis pour la prendre.
- `side` (code ou null) : Camp qui peut la faire. Valeurs : `alliance`, `horde`, `both`.
- `side_name` (chaîne ou null) : Camp, libellé français.
- `type` (code ou null) : Type de quête du jeu (groupe, donjon, raid…) ; null pour une quête normale. Valeurs : `group`, `elite`, `dungeon`, `raid`, `heroic`, `pvp`, `escort`, `legendary`, `world_event`, `life`, `other`.
- `type_name` (chaîne ou null) : Type, libellé français.
- `daily` (booléen) : Quête journalière.
- `weekly` (booléen) : Quête hebdomadaire.
- `repeatable` (booléen) : Quête répétable.
- `category` (objet ou null) : Catégorie du journal de quêtes : une zone ou une catégorie du jeu (classe, métier, événement).
  - `type` (chaîne) : « zone » ou « sort » (catégorie du jeu).
  - `id` (entier ou null) : Numéro de la zone ou de la catégorie (filtre zone des listes).
  - `name` (chaîne) : Nom français.
- `instance` (InstanceRef ou null) : Donjon ou raid de la quête.
- `xp` (entier ou null) : Expérience gagnée.
- `money` (entier ou null) : Argent gagné, en cuivre.
- `reward_items` (tableau d’objets) : Objets de récompense, donnés ou au choix.
  - `item` (ItemRef) : L’objet.
  - `choice` (booléen) : Vrai si c’est une récompense au choix.
- `rogue` (booléen) : Utile au voleur (récompense ou objectif qui le concerne, quête de classe).
- `internal` (booléen) : Quête interne du jeu (jamais sortie) : absente des listes et de la recherche.
- `url` (chaîne) : Adresse publique de la fiche sur WoWDB (page HTML, à donner à vos lecteurs).
- `api_url` (chaîne) : Adresse de la quête dans l’API.

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

- `max_level` (entier ou null) : Niveau maximum pour la prendre.
- `players` (entier ou null) : Nombre de joueurs conseillé.
- `shareable` (booléen ou null) : Partageable avec le groupe.
- `time_limit_text` (chaîne ou null) : Temps limité, en clair (« 15 min »).
- `races` (chaîne ou null) : Races qui peuvent la prendre, en clair ; null pour toutes.
- `classes` (chaîne ou null) : Classes qui peuvent la prendre, en clair ; null pour toutes.
- `skill` (objet ou null) : Métier requis.
  - `name` (chaîne) : Métier.
  - `level` (entier) : Niveau de métier.
- `objectives` (chaîne ou null) : Objectifs, texte du jeu.
- `description` (chaîne ou null) : Description, texte du jeu.
- `progress` (chaîne ou null) : Texte de progression (quête pas encore finie).
- `completion` (chaîne ou null) : Texte de fin.
- `requirements` (tableau d’objets) : Ce qu’il faut faire ou rapporter.
  - `kind` (chaîne) : item (objet à rapporter), creature, object (objet du monde), money, reputation, players, explore ou text.
  - `name` (chaîne ou null) : Nom de l’objectif.
  - `quantity` (entier ou null) : Quantité.
  - `record` (Ref ou null) : Fiche de l’objet, de la créature ou de la réputation.
  - `money` (entier ou null, facultatif) : Argent demandé, en cuivre (kind money).
  - `rank_name` (chaîne ou null, facultatif) : Rang à atteindre (kind reputation).
  - `value` (entier ou null, facultatif) : Valeur de réputation (kind reputation).
  - `zones` (tableau de chaînes, facultatif) : Zones de l’objectif.
  - `instance` (InstanceRef ou null, facultatif) : Donjon de l’objectif.
  - `text` (chaîne ou null, facultatif) : Libellé du jeu, quand il diffère du nom.
- `rewards` (objet) : Récompenses.
  - `items` (tableau d’objets) : Objets donnés : item (ItemRef ou null), name, quantity.
  - `choices` (tableau d’objets) : Objets au choix : item, name, quantity.
  - `money` (entier ou null) : Argent, en cuivre.
  - `money_max_level` (entier ou null) : Argent au niveau maximum, en cuivre.
  - `xp` (entier ou null) : Expérience.
  - `spell` (objet ou null) : Sort appris : name et spell (Ref ou null).
  - `title` (chaîne ou null) : Titre obtenu.
  - `honor` (entier ou null) : Points d’honneur.
  - `arena` (entier ou null) : Points d’arène.
  - `talents` (entier ou null) : Points de talent.
  - `reputation` (tableau d’objets) : Réputation gagnée : faction (Ref ou null), name, value.
- `starts` (tableau d’objets) : Qui donne la quête.
  - `type` (chaîne) : npc, item (objet qui commence la quête) ou game_object.
  - `name` (chaîne ou null) : Nom.
  - `record` (Ref ou null) : Sa fiche.
  - `zones` (tableau de chaînes) : Zones où le trouver.
  - `instance` (InstanceRef ou null) : Donjon où le trouver.
- `ends` (tableau d’objets) : Qui reprend la quête (mêmes champs que starts).
- `chain` (objet ou null) : Suite de quêtes.
  - `previous` (tableau de Ref) : À faire avant.
  - `follows` (tableau de Ref) : Quête dont elle est la suite directe.
  - `next` (tableau de Ref) : Quêtes ouvertes ensuite.
  - `direct` (tableau de Ref) : Suite directe, proposée aussitôt.
  - `exclusive` (tableau de Ref) : Quêtes exclusives : une seule possible.
  - `group` (tableau de Ref) : Quêtes du même ensemble.
  - `opened_by` (ItemRef ou null) : Objet qui ouvre la quête.
- `versions` (tableau de Ref) : La même fiche dans chaque version du jeu où elle existe (elle comprise).
- `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 : quête** (statut 200)

```json
{
  "object": "quest",
  "id": 166,
  "key": "classic:quest:166",
  "version": "classic",
  "name": "La Confrérie défias",
  "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_note_01.jpg",
  "level": 22,
  "required_level": 14,
  "side": "alliance",
  "side_name": "Alliance",
  "type": "dungeon",
  "type_name": "Donjon",
  "daily": false,
  "weekly": false,
  "repeatable": false,
  "category": {
    "type": "zone",
    "id": 1581,
    "name": "Les Mortemines"
  },
  "instance": {
    "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"
  },
  "xp": 2600,
  "money": null,
  "reward_items": [
    {
      "item": {
        "object": "item",
        "id": 6087,
        "version": "classic",
        "name": "Haut-de-chausses de la marche de l'Ouest",
        "quality": "rare",
        "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_pants_03.webp",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:6087",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/6087"
      },
      "choice": true
    },
    {
      "item": {
        "object": "item",
        "id": 2041,
        "version": "classic",
        "name": "Tunique de la marche de l'Ouest",
        "quality": "rare",
        "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_chest_leather_07.jpg",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2041",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2041"
      },
      "choice": true
    },
    {
      "item": {
        "object": "item",
        "id": 2042,
        "version": "classic",
        "name": "Bâton de la marche de l'Ouest",
        "quality": "rare",
        "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_staff_10.webp",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2042",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2042"
      },
      "choice": true
    }
  ],
  "rogue": true,
  "internal": false,
  "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:166",
  "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/166",
  "max_level": null,
  "players": null,
  "shareable": true,
  "time_limit_text": null,
  "races": null,
  "classes": null,
  "skill": null,
  "objectives": "Tuer Edwin VanCleef et apporter sa Tête à Gryan Roidemantel.",
  "description": "Il vous reste une dernière mission à accomplir. Il va falloir éliminer Edwin VanCleef. Bien que cela me chagrine de condamner un homme à mort, c'est pour le bien du peuple de la marche de l'Ouest que VanCleef doit mourir. Apportez-moi sa tête lorsque l'acte sera accompli.",
  "progress": "Alors, comment se passe cette chasse à l'homme pour Edwin VanCleef ?",
  "completion": "<nom>, votre bravoure est extraordinaire. La Milice du peuple vous remercie pour les services rendus au peuple de la marche de l'Ouest. VanCleef est mort, et sa mort marque le début de la chute de la Confrérie Défias. Nous pouvons espérer maintenant qu'un jour la paix revienne sur ce beau pays !\n\nJe vous salue, Seigneur !",
  "requirements": [
    {
      "kind": "item",
      "name": "Tête de VanCleef",
      "quantity": 1,
      "record": {
        "object": "item",
        "id": 3637,
        "version": "classic",
        "name": "Tête de VanCleef",
        "quality": "common",
        "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_head_human_01.webp",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:3637",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/3637"
      }
    }
  ],
  "rewards": {
    "items": [],
    "choices": [
      {
        "item": {
          "object": "item",
          "id": 6087,
          "version": "classic",
          "name": "Haut-de-chausses de la marche de l'Ouest",
          "quality": "rare",
          "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_pants_03.webp",
          "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:6087",
          "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/6087"
        },
        "name": "Haut-de-chausses de la marche de l'Ouest",
        "quantity": 1
      },
      {
        "item": {
          "object": "item",
          "id": 2041,
          "version": "classic",
          "name": "Tunique de la marche de l'Ouest",
          "quality": "rare",
          "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_chest_leather_07.jpg",
          "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2041",
          "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2041"
        },
        "name": "Tunique de la marche de l'Ouest",
        "quantity": 1
      },
      {
        "item": {
          "object": "item",
          "id": 2042,
          "version": "classic",
          "name": "Bâton de la marche de l'Ouest",
          "quality": "rare",
          "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_staff_10.webp",
          "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2042",
          "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2042"
        },
        "name": "Bâton de la marche de l'Ouest",
        "quantity": 1
      }
    ],
    "money": null,
    "money_max_level": 1560,
    "xp": 2600,
    "spell": null,
    "title": null,
    "honor": null,
    "arena": null,
    "talents": null,
    "reputation": [
      {
        "faction": {
          "object": "faction",
          "id": 72,
          "version": "classic",
          "name": "Hurlevent",
          "url": "https://wowdb.assemblee-defias.fr/?id=classic:faction:72",
          "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/factions/72"
        },
        "name": "Hurlevent",
        "value": 500
      }
    ]
  },
  "starts": [
    {
      "type": "npc",
      "name": "Maréchal Gryan Roidemantel",
      "record": {
        "object": "npc",
        "id": 234,
        "version": "classic",
        "name": "Maréchal Gryan Roidemantel",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:234",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/234"
      },
      "zones": [
        "Marche de l'Ouest"
      ],
      "instance": null
    }
  ],
  "ends": [
    {
      "type": "npc",
      "name": "Maréchal Gryan Roidemantel",
      "record": {
        "object": "npc",
        "id": 234,
        "version": "classic",
        "name": "Maréchal Gryan Roidemantel",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:234",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/234"
      },
      "zones": [
        "Marche de l'Ouest"
      ],
      "instance": null
    }
  ],
  "chain": {
    "previous": [],
    "follows": [
      {
        "object": "quest",
        "id": 155,
        "version": "classic",
        "name": "La Confrérie défias",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:155",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/155"
      }
    ],
    "next": [],
    "direct": [],
    "exclusive": [],
    "group": [],
    "opened_by": null
  },
  "versions": [
    {
      "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"
    },
    {
      "object": "quest",
      "id": 166,
      "version": "tbc",
      "name": "La Confrérie défias",
      "url": "https://wowdb.assemblee-defias.fr/?id=tbc:quest:166",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/tbc/quests/166"
    },
    {
      "object": "quest",
      "id": 166,
      "version": "wotlk",
      "name": "La Confrérie défias",
      "url": "https://wowdb.assemblee-defias.fr/?id=wotlk:quest:166",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/wotlk/quests/166"
    }
  ],
  "guides": []
}
```

## Lister les quêtes

`GET /v1/{version}/quests`

Toutes les quêtes d’une version (quêtes internes exclues), avec leurs récompenses résumées.

**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`.
- `q` (chaîne, facultatif) : Filtre sur le nom : chaque mot doit commencer un mot du nom (« lame om » trouve « Lame de l’ombre »). Sans accent ni majuscule nécessaires.
- `side` (codes séparés par des virgules, facultatif) : Camps. Plusieurs valeurs séparées par des virgules. Valeurs : `alliance`, `horde`, `both`.
- `type` (codes séparés par des virgules, facultatif) : Types de quête ; daily, weekly et repeatable filtrent les quêtes journalières, hebdomadaires et répétables. Plusieurs valeurs séparées par des virgules. Valeurs : `group`, `elite`, `dungeon`, `raid`, `heroic`, `pvp`, `escort`, `legendary`, `world_event`, `life`, `other`, `daily`, `weekly`, `repeatable`.
- `zone` (entier, facultatif) : Numéro de la zone du journal de quêtes (category.id ; 1581 : Les Mortemines).
- `min_level` (entier, facultatif) : Niveau de la quête minimum (1 à 100).
- `max_level` (entier, facultatif) : Niveau de la quête maximum (1 à 100).
- `rogue` (booléen, facultatif) : true : seulement les quêtes utiles au voleur ; false : seulement les autres. Absent : tout (par défaut).
- `sort` (chaîne, facultatif) : Ordre : name, level, xp ; « - » devant inverse l’ordre (-item_level : du plus haut au plus bas). Valeurs vides en fin de liste. Par défaut : name. Valeurs : `name`, `-name`, `level`, `-level`, `xp`, `-xp`.
- `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 `quest`, paginée par curseur.

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

#### cURL

```bash
curl -G https://api.wowdb.assemblee-defias.fr/v1/classic/quests \
  -d zone=1581 \
  -d side=alliance \
  -d sort=level \
  -d limit=2
```

#### JavaScript

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

#### Python

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

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

#### PHP

```php
<?php
$params = http_build_query([
    'zone' => '1581',
    'side' => 'alliance',
    'sort' => 'level',
    '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/quests?' . $params, false, $context);
$page = json_decode($json, true);
foreach ($page['data'] as $quest) {
    echo $quest['name'], PHP_EOL;
}
```

#### Ruby

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

uri = URI("https://api.wowdb.assemblee-defias.fr/v1/classic/quests")
uri.query = URI.encode_www_form(
  zone: "1581",
  side: "alliance",
  sort: "level",
  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 |quest|
  puts quest["name"]
end
```

#### Go

```go
package main

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

func main() {
	params := url.Values{}
	params.Set("zone", "1581")
	params.Set("side", "alliance")
	params.Set("sort", "level")
	params.Set("limit", "2")
	req, err := http.NewRequest("GET", "https://api.wowdb.assemblee-defias.fr/v1/classic/quests?"+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 _, quest := range page.Data {
		fmt.Println(quest["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/quests?zone=1581&side=alliance&sort=level&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/quests?zone=1581&side=alliance&sort=level&limit=2");
using var doc = JsonDocument.Parse(json);
foreach (var quest in doc.RootElement.GetProperty("data").EnumerateArray())
    Console.WriteLine(quest.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/quests")
        .set("User-Agent", "mon-application/1.0 (contact@example.com)")
        .query("zone", "1581")
        .query("side", "alliance")
        .query("sort", "level")
        .query("limit", "2")
        .call()?
        .into_json()?;
    for quest in page["data"].as_array().into_iter().flatten() {
        println!("{}", quest["name"].as_str().unwrap_or_default());
    }
    Ok(())
}
```

**Réponse** (statut 200)

```json
{
  "object": "list",
  "data": [
    {
      "object": "quest",
      "id": 214,
      "key": "classic:quest:214",
      "version": "classic",
      "name": "Les masques rouges en soie",
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_note_01.jpg",
      "level": 17,
      "required_level": 14,
      "side": "alliance",
      "side_name": "Alliance",
      "type": "dungeon",
      "type_name": "Donjon",
      "daily": false,
      "weekly": false,
      "repeatable": false,
      "category": {
        "type": "zone",
        "id": 1581,
        "name": "Les Mortemines"
      },
      "instance": {
        "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"
      },
      "xp": 1250,
      "money": null,
      "reward_items": [
        {
          "item": {
            "object": "item",
            "id": 2074,
            "version": "classic",
            "name": "Lame courte solide",
            "quality": "uncommon",
            "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_sword_23.webp",
            "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2074",
            "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2074"
          },
          "choice": true
        },
        {
          "item": {
            "object": "item",
            "id": 2089,
            "version": "classic",
            "name": "Dague en ivoire imagé",
            "quality": "uncommon",
            "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_weapon_shortblade_01.webp",
            "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2089",
            "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2089"
          },
          "choice": true
        },
        {
          "item": {
            "object": "item",
            "id": 6094,
            "version": "classic",
            "name": "Hache perforante",
            "quality": "uncommon",
            "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_throwingaxe_01.webp",
            "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:6094",
            "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/6094"
          },
          "choice": true
        }
      ],
      "rogue": true,
      "internal": false,
      "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:214",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/214"
    },
    {
      "object": "quest",
      "id": 168,
      "key": "classic:quest:168",
      "version": "classic",
      "name": "À la recherche de cartes du syndicat des mineurs",
      "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_note_01.jpg",
      "level": 18,
      "required_level": 14,
      "side": "alliance",
      "side_name": "Alliance",
      "type": null,
      "type_name": null,
      "daily": false,
      "weekly": false,
      "repeatable": false,
      "category": {
        "type": "zone",
        "id": 1581,
        "name": "Les Mortemines"
      },
      "instance": {
        "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"
      },
      "xp": 1350,
      "money": null,
      "reward_items": [
        {
          "item": {
            "object": "item",
            "id": 2037,
            "version": "classic",
            "name": "Bottes de tunnelier",
            "quality": "uncommon",
            "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_boots_01.jpg",
            "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2037",
            "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2037"
          },
          "choice": true
        },
        {
          "item": {
            "object": "item",
            "id": 2036,
            "version": "classic",
            "name": "Gants de mine poussiéreux",
            "quality": "uncommon",
            "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_gauntlets_05.webp",
            "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2036",
            "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2036"
          },
          "choice": true
        }
      ],
      "rogue": true,
      "internal": false,
      "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:168",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/168"
    }
  ],
  "has_more": true,
  "next_cursor": "eyJrIjpbMTgsImEgbGEgcmVjaGVyY2hlIGRlIGNhcnRlcyBkdSBzeW5kaWNhdCBkZXMgbWluZXVycyIsImNsYXNzaWM6cXVlc3Q6MTY4Il0sImgiOiI3U1NVdVFVZkVEIn0",
  "url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests?side=alliance&sort=level&zone=1581"
}
```

## Obtenir une quête

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

La fiche complète de la quête : 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 de la quête.

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

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

#### cURL

```bash
curl https://api.wowdb.assemblee-defias.fr/v1/classic/quests/166
```

#### JavaScript

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

#### Python

```python
import json
import urllib.request

req = urllib.request.Request(
    "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/166",
    headers={"User-Agent": "mon-application/1.0 (contact@example.com)"},
)
with urllib.request.urlopen(req) as res:
    quest = json.load(res)
print(quest["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/quests/166', false, $context);
$quest = json_decode($json, true);
echo $quest['name'], PHP_EOL;
```

#### Ruby

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

uri = URI("https://api.wowdb.assemblee-defias.fr/v1/classic/quests/166")
res = Net::HTTP.get_response(uri, { "User-Agent" => "mon-application/1.0 (contact@example.com)" })
quest = JSON.parse(res.body)
puts quest["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/quests/166", 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 quest map[string]any
	if err := json.NewDecoder(res.Body).Decode(&quest); err != nil {
		panic(err)
	}
	fmt.Println(quest["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/quests/166"))
            .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/quests/166");
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 quest: serde_json::Value = ureq::get("https://api.wowdb.assemblee-defias.fr/v1/classic/quests/166")
        .set("User-Agent", "mon-application/1.0 (contact@example.com)")
        .call()?
        .into_json()?;
    println!("{}", quest["name"].as_str().unwrap_or_default());
    Ok(())
}
```

**Réponse** (statut 200)

```json
{
  "object": "quest",
  "id": 166,
  "key": "classic:quest:166",
  "version": "classic",
  "name": "La Confrérie défias",
  "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_note_01.jpg",
  "level": 22,
  "required_level": 14,
  "side": "alliance",
  "side_name": "Alliance",
  "type": "dungeon",
  "type_name": "Donjon",
  "daily": false,
  "weekly": false,
  "repeatable": false,
  "category": {
    "type": "zone",
    "id": 1581,
    "name": "Les Mortemines"
  },
  "instance": {
    "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"
  },
  "xp": 2600,
  "money": null,
  "reward_items": [
    {
      "item": {
        "object": "item",
        "id": 6087,
        "version": "classic",
        "name": "Haut-de-chausses de la marche de l'Ouest",
        "quality": "rare",
        "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_pants_03.webp",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:6087",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/6087"
      },
      "choice": true
    },
    {
      "item": {
        "object": "item",
        "id": 2041,
        "version": "classic",
        "name": "Tunique de la marche de l'Ouest",
        "quality": "rare",
        "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_chest_leather_07.jpg",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2041",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2041"
      },
      "choice": true
    },
    {
      "item": {
        "object": "item",
        "id": 2042,
        "version": "classic",
        "name": "Bâton de la marche de l'Ouest",
        "quality": "rare",
        "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_staff_10.webp",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2042",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2042"
      },
      "choice": true
    }
  ],
  "rogue": true,
  "internal": false,
  "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:166",
  "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/166",
  "max_level": null,
  "players": null,
  "shareable": true,
  "time_limit_text": null,
  "races": null,
  "classes": null,
  "skill": null,
  "objectives": "Tuer Edwin VanCleef et apporter sa Tête à Gryan Roidemantel.",
  "description": "Il vous reste une dernière mission à accomplir. Il va falloir éliminer Edwin VanCleef. Bien que cela me chagrine de condamner un homme à mort, c'est pour le bien du peuple de la marche de l'Ouest que VanCleef doit mourir. Apportez-moi sa tête lorsque l'acte sera accompli.",
  "progress": "Alors, comment se passe cette chasse à l'homme pour Edwin VanCleef ?",
  "completion": "<nom>, votre bravoure est extraordinaire. La Milice du peuple vous remercie pour les services rendus au peuple de la marche de l'Ouest. VanCleef est mort, et sa mort marque le début de la chute de la Confrérie Défias. Nous pouvons espérer maintenant qu'un jour la paix revienne sur ce beau pays !\n\nJe vous salue, Seigneur !",
  "requirements": [
    {
      "kind": "item",
      "name": "Tête de VanCleef",
      "quantity": 1,
      "record": {
        "object": "item",
        "id": 3637,
        "version": "classic",
        "name": "Tête de VanCleef",
        "quality": "common",
        "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_misc_head_human_01.webp",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:3637",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/3637"
      }
    }
  ],
  "rewards": {
    "items": [],
    "choices": [
      {
        "item": {
          "object": "item",
          "id": 6087,
          "version": "classic",
          "name": "Haut-de-chausses de la marche de l'Ouest",
          "quality": "rare",
          "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_pants_03.webp",
          "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:6087",
          "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/6087"
        },
        "name": "Haut-de-chausses de la marche de l'Ouest",
        "quantity": 1
      },
      {
        "item": {
          "object": "item",
          "id": 2041,
          "version": "classic",
          "name": "Tunique de la marche de l'Ouest",
          "quality": "rare",
          "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_chest_leather_07.jpg",
          "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2041",
          "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2041"
        },
        "name": "Tunique de la marche de l'Ouest",
        "quantity": 1
      },
      {
        "item": {
          "object": "item",
          "id": 2042,
          "version": "classic",
          "name": "Bâton de la marche de l'Ouest",
          "quality": "rare",
          "icon": "https://wowdb.assemblee-defias.fr/database-icons/inv_staff_10.webp",
          "url": "https://wowdb.assemblee-defias.fr/?id=classic:item:2042",
          "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/items/2042"
        },
        "name": "Bâton de la marche de l'Ouest",
        "quantity": 1
      }
    ],
    "money": null,
    "money_max_level": 1560,
    "xp": 2600,
    "spell": null,
    "title": null,
    "honor": null,
    "arena": null,
    "talents": null,
    "reputation": [
      {
        "faction": {
          "object": "faction",
          "id": 72,
          "version": "classic",
          "name": "Hurlevent",
          "url": "https://wowdb.assemblee-defias.fr/?id=classic:faction:72",
          "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/factions/72"
        },
        "name": "Hurlevent",
        "value": 500
      }
    ]
  },
  "starts": [
    {
      "type": "npc",
      "name": "Maréchal Gryan Roidemantel",
      "record": {
        "object": "npc",
        "id": 234,
        "version": "classic",
        "name": "Maréchal Gryan Roidemantel",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:234",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/234"
      },
      "zones": [
        "Marche de l'Ouest"
      ],
      "instance": null
    }
  ],
  "ends": [
    {
      "type": "npc",
      "name": "Maréchal Gryan Roidemantel",
      "record": {
        "object": "npc",
        "id": 234,
        "version": "classic",
        "name": "Maréchal Gryan Roidemantel",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:npc:234",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/npcs/234"
      },
      "zones": [
        "Marche de l'Ouest"
      ],
      "instance": null
    }
  ],
  "chain": {
    "previous": [],
    "follows": [
      {
        "object": "quest",
        "id": 155,
        "version": "classic",
        "name": "La Confrérie défias",
        "url": "https://wowdb.assemblee-defias.fr/?id=classic:quest:155",
        "api_url": "https://api.wowdb.assemblee-defias.fr/v1/classic/quests/155"
      }
    ],
    "next": [],
    "direct": [],
    "exclusive": [],
    "group": [],
    "opened_by": null
  },
  "versions": [
    {
      "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"
    },
    {
      "object": "quest",
      "id": 166,
      "version": "tbc",
      "name": "La Confrérie défias",
      "url": "https://wowdb.assemblee-defias.fr/?id=tbc:quest:166",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/tbc/quests/166"
    },
    {
      "object": "quest",
      "id": 166,
      "version": "wotlk",
      "name": "La Confrérie défias",
      "url": "https://wowdb.assemblee-defias.fr/?id=wotlk:quest:166",
      "api_url": "https://api.wowdb.assemblee-defias.fr/v1/wotlk/quests/166"
    }
  ],
  "guides": []
}
```

---

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.
