> ## Documentation Index
> Fetch the complete documentation index at: https://www.octoparse.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Assembler un dossier de contrat

> Fusionner le JSON de contrat multi-fichiers en un manifest entièrement validé. Accès anonyme autorisé.

**`POST`** `https://api-datahub.octoparse.com/v1/data-apps/contract/assemble`

Authentification : aucune. Accès anonyme autorisé.

Fusionne un dossier de contrat (map de fichiers par chemin relatif, ordre conservé) en un manifest autonome. Cet endpoint est la seule source de vérité des règles d’assemblage. Le wizard d’import du portail et le self-check du skill de contrat l’utilisent.

Fichiers de slot : `dataapp.json` / `input_schema.json` / `output_schema.json` / `runtime.json` / `pricing.json` / `examples.json` / `README.md` (noms insensibles à la casse ; formes pointées comme `input.schema.json` acceptées et normalisées dans `picked`). Tarifs et exemples peuvent aussi être inline dans `dataapp.json`. Le manifest fusionné passe la validation complète côté auteur (mêmes règles que Valider un manifest). Livrable seulement si `issues` est vide. Les anomalies récupérables (fichiers manquants, collisions de noms entre couches, fichiers non-contrat ignorés, décalage de nom de dossier, etc.) reviennent en `warnings` structurés (`code` + `params`, localisés par la couche de présentation) et ne sont pas des erreurs.

Échecs durs (`400`) : un fichier de slot n’est pas un JSON valide, a une mauvaise forme (`examples.json` doit être un array, etc.) ou un fichier dépasse 1 Mo / le total 4 Mo. Soft : anomalies récupérables en `warnings`.

Le 8e fichier optionnel `i18n.json` (`{source, locales}`, jusqu’à 4 Mo) **n’est pas** fusionné dans le manifest : validé en forme et renvoyé séparément dans `translations` pour que l’appelant décide quand sauver les overlays. Sans fichier, `translations` est `null`.

Accès anonyme autorisé : l’assemblage est une fonction pure du corps, ne lit ni n’écrit de données plateforme, et les limites de taille sont la seule porte.

## Requête

### Corps de la requête

<ParamField body="files" type="object" required>
  Map de fichiers. Clés = chemins relatifs ; valeurs = texte du fichier.
</ParamField>

### Exemple de requête

```bash theme={null}
curl -X POST \
  -H "Content-Type: application/json" \
  -d '{"files": {"dataapp.json": "{\"spec_version\": \"0.2\", \"identity\": {…}}", "input_schema.json": "{\"type\": \"object\", …}", "output_schema.json": "{\"id_field\": \"review_id\", …}", "runtime.json": "{\"kind\": \"api\", …}", "pricing.json": "{\"events\": [...]}", "examples.json": "[...]", "README.md": "# Product review lookup"}}' \
  "https://api-datahub.octoparse.com/v1/data-apps/contract/assemble"
```

## Réponse

### 200 succès

```json theme={null}
{
  "data": {
    "manifest": {
      "spec_version": "0.2",
      "identity": {
        "app_name": "reviews-query",
        "name": "Product review lookup"
      },
      "…": "…"
    },
    "picked": {
      "dataapp.json": "dataapp.json",
      "input_schema.json": "input_schema.json"
    },
    "issues": [],
    "warnings": [
      {
        "code": "contract-folder-name-mismatch",
        "params": {
          "expected": "reviews-query",
          "actual": "reviews"
        }
      }
    ],
    "card": {
      "app_name": "reviews-query",
      "name": "Product review lookup"
    },
    "translations": null
  }
}
```

La charge utile est encapsulée dans `data`. Champs :

<ResponseField name="manifest" type="object" required>
  Objet manifest fusionné.
</ResponseField>

<ResponseField name="picked" type="string[]">
  Map des fichiers de slot réellement reconnus.
</ResponseField>

<ResponseField name="folder_name" type="string">
  —
</ResponseField>

<ResponseField name="issues" type="object[]">
  Problèmes de validation. Vide = livrable.

  <Expandable title="champs">
    <ResponseField name="path" type="string" required>
      —
    </ResponseField>

    <ResponseField name="message" type="string" required>
      —
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="warnings" type="object[]">
  Avertissements structurés.

  <Expandable title="champs">
    <ResponseField name="code" type="string" required>
      —
    </ResponseField>

    <ResponseField name="params" type="object">
      —
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="translations" type="object">
  Contenu parsé de `i18n.json`, ou `null` s’il est absent.

  <Expandable title="champs">
    <ResponseField name="source" type="string" required>
      —
    </ResponseField>

    <ResponseField name="locales" type="object">
      —
    </ResponseField>
  </Expandable>
</ResponseField>

### Erreurs

| HTTP | `code`                  | `category`      | Description                                                                                                                 |
| ---- | ----------------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------- |
| 400  | `contract-file-invalid` | `invalid_input` | Un fichier de contrat n’est pas un JSON valide, a une mauvaise forme, ou dépasse 1 Mo ; ou `i18n.json` n’a pas de `source`. |
| 400  | `contract-empty`        | `invalid_input` | Le jeu de fichiers ne contient aucun slot de contrat.                                                                       |
| 400  | `locale-invalid`        | `invalid_input` | Le code de locale est invalide.                                                                                             |
| 413  | `payload-too-large`     | `invalid_input` | Le corps dépasse la limite de taille.                                                                                       |

Les réponses d’erreur utilisent `{"error": {code, category, message, retryable}}`. Voir <a href="/docs/fr/datahub/api/reference/introduction#errors">Erreurs</a>.

## Bibliothèques clientes

Les SDK Python et JavaScript n’encapsulent pas encore cet endpoint. Appelez REST directement.
