> ## 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.

# Vertragsordner zusammensetzen

> Multi-File-Contract-JSON zu einem voll validierten Manifest mergen. Anonymer Zugriff erlaubt.

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

Authentifizierung: keine. Anonymer Zugriff erlaubt.

Führt einen Vertragsordner (eine nach relativem Pfad geschlüsselte Datei-Map, Reihenfolge bleibt erhalten) zu einem in sich geschlossenen Manifest zusammen. Dieser Endpoint ist die einzige verbindliche Quelle für die Zusammenbauregeln. Der Import-Assistent des Portals und der Selbsttest des Contract-Skills verwenden ihn beide.

Slot-Dateien: `dataapp.json`/⟦1/`output_schema.json`/`runtime.json`/`pricing.json`/`examples.json` ⟧/`README.md` (Dateinamen sind unabhängig von der Groß- und Kleinschreibung; gepunktete Formen wie `input.schema.json` werden akzeptiert und in ⟦8 normalisiert⟧). Preise und Beispiele können auch in ⟦9 angegeben werden⟧. Das zusammengeführte Manifest durchläuft eine vollständige autorseitige Validierung (dieselben Regeln wie Manifest validieren). Nur lieferbar, wenn ⟦10 leer⟧ ist. Behebbare Anomalien (fehlende Dateien, schichtenübergreifende Namenskollisionen, ignorierte Nichtvertragsdateien, Fehlanpassung von Ordnernamen usw.) werden als strukturiert `warnings` (`code` + `params`, lokalisiert durch die Präsentationsschicht) zurückgegeben und sind keine Fehler.

Hard Failures (`400`): Slot-Datei ist kein gültiges JSON, hat die falsche Form (`examples.json` muss Array sein; andere Slots sind Objekte) oder überschreitet 1MB; gar keine Contract-Datei; Gesamtgröße über 12MB. Der Contract-Pfad deckt nur api-kind ab; `runtime.kind=code` erzeugt ein Issue.

Optionale 8. Datei `i18n.json` (`{source, locales}`, bis 4MB) wird **nicht** in das Manifest gemerged. Sie wird geparst und als `translations` zurückgegeben, damit der Caller sie über die Übersetzungs-Endpoints speichern kann. `source` sollte mit `source_locale` der App übereinstimmen.

Anonymer Zugriff erlaubt: Assembly ist reine Funktion des Request-Bodys, liest/schreibt keine Plattformdaten; einzige Gates sind Datei-/Gesamtgrößenlimits.

## Anfrage

### Anfrage-Body

<ParamField body="files" type="object" required>
  Datei-Map. Schlüssel sind relative Pfade; Werte sind Dateitexte.
</ParamField>

### Beispielanfrage

```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"
```

## Antwort

### 200 Erfolg

```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
  }
}
```

Payload ist in `data` gewrappt. Felder:

<ResponseField name="manifest" type="object" required>
  Zusammengeführtes Manifest-Objekt.
</ResponseField>

<ResponseField name="picked" type="string[]">
  Map der tatsächlich erkannten Slot-Dateien.
</ResponseField>

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

<ResponseField name="issues" type="object[]">
  Validierungsprobleme. Leer bedeutet auslieferbar.

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

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

<ResponseField name="warnings" type="object[]">
  Strukturierte Warnungen.

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

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

<ResponseField name="translations" type="object">
  Geparster Inhalt von `i18n.json` oder `null`, wenn nicht vorhanden.

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

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

### Fehler

| HTTP | `code`                  | `category`      | Beschreibung                                                                                                                    |
| ---- | ----------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| 400  | `contract-file-invalid` | `invalid_input` | Eine Vertragsdatei ist kein gültiges JSON, hat die falsche Struktur oder überschreitet 1MB; oder in `i18n.json` fehlt `source`. |
| 400  | `contract-empty`        | `invalid_input` | Das Dateiset enthält keine Contract-Slot-Dateien.                                                                               |
| 400  | `locale-invalid`        | `invalid_input` | Locale-Code ist ungültig.                                                                                                       |
| 413  | `payload-too-large`     | `invalid_input` | Request-Body überschreitet das Größenlimit.                                                                                     |

Fehlerantworten nutzen `{"error": {code, category, message, retryable}}`. Siehe <a href="/docs/de/datahub/api/reference/introduction#errors">Fehler</a>.

## Client-Bibliotheken

Die Python- und JavaScript-SDKs wrappen diesen Endpoint noch nicht. REST direkt aufrufen.
