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

# Enrich API Reference

> Complete API documentation for the Enrich endpoint

## POST /public/enrich

Enrich items with AI-powered web research. Every extracted field includes source URLs.

<CodeGroup>
  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://catalogapi.rastro.ai/api/public/enrich",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      json={
          "items": [{"part_number": "6205-2RS", "name": "Deep Groove Ball Bearing"}],
          "output_schema": [
              {"name": "bore_diameter", "type": "string", "description": "Inner diameter in mm"},
              {"name": "outer_diameter", "type": "string", "description": "Outer diameter in mm"}
          ]
      }
  )
  ```

  ```bash cURL theme={null}
  curl -X POST "https://catalogapi.rastro.ai/api/public/enrich" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "items": [{"part_number": "6205-2RS", "name": "Deep Groove Ball Bearing"}],
      "output_schema": [
        {"name": "bore_diameter", "type": "string", "description": "Inner diameter in mm"},
        {"name": "outer_diameter", "type": "string", "description": "Outer diameter in mm"}
      ]
    }'
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch("https://catalogapi.rastro.ai/api/public/enrich", {
    method: "POST",
    headers: { "Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json" },
    body: JSON.stringify({
      items: [{ part_number: "6205-2RS", name: "Deep Groove Ball Bearing" }],
      output_schema: [
        { name: "bore_diameter", type: "string", description: "Inner diameter in mm" },
        { name: "outer_diameter", type: "string", description: "Outer diameter in mm" }
      ]
    })
  });
  ```
</CodeGroup>

***

## Request Parameters

### Core Parameters

| Parameter          | Type   | Required    | Default | Description                                                                                                                                            |
| ------------------ | ------ | ----------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `items`            | array  | Conditional | `[]`    | JSON objects to enrich. Required unless you provide `source_activity_id`, `reextract_from_activity_id`, `source_catalog_id`, or multipart `items_file` |
| `output_schema`    | array  | Conditional | `[]`    | Fields to extract. Required unless supplied by `catalog_id`, `template_id`, or a source activity/catalog                                               |
| `prompt`           | string | No          | `""`    | Search prompt guiding web research                                                                                                                     |
| `template_id`      | string | No          | -       | Apply an organization-scoped enrichment template. Template defaults fill omitted request fields and template safety controls remain enforced           |
| `attribute_sets`   | object | No          | -       | Registry for repeated requested-attribute definitions. Items reference entries with `attribute_set_id`                                                 |
| `source_hint_sets` | object | No          | -       | Registry for repeated source hints. Items reference entries with `source_hint_set_id`                                                                  |

### Search Options

| Parameter         | Type    | Default  | Description                                                                                                                        |
| ----------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `speed`           | string  | `"deep"` | `"fast"` (quick), `"medium"` (balanced), `"deep"`/`"slow"` (thorough), `"ultra_slow"` (maximum reasoning), `"cheap"` (lowest cost) |
| `allowed_domains` | array   | any      | Restrict sources to these domains only                                                                                             |
| `blocked_domains` | array   | -        | Exclude these domains from search and URL fetching                                                                                 |
| `web_search`      | boolean | `true`   | Set `false` to skip web search and use input data directly                                                                         |

### Taxonomy & Quality

| Parameter                     | Type    | Default | Description                                                          |
| ----------------------------- | ------- | ------- | -------------------------------------------------------------------- |
| `taxonomy`                    | object  | -       | Taxonomy definition for category prediction                          |
| `predict_taxonomy`            | boolean | `false` | Predict category for each item                                       |
| `predict_taxonomy_attributes` | boolean | `true`  | Predict category-specific `taxonomy_attributes` after classification |
| `validate_semantics`          | boolean | `false` | AI validates values match field descriptions                         |
| `low_confidence`              | object  | -       | Return plausible but weak candidates outside canonical output        |

### Job Control

| Parameter                     | Type    | Default | Description                                                                                          |
| ----------------------------- | ------- | ------- | ---------------------------------------------------------------------------------------------------- |
| `catalog_id`                  | string  | -       | Catalog ID from the dashboard — automatically applies its schema, taxonomy, and settings             |
| `source_catalog_id`           | string  | -       | Read all items from this catalog as enrichment input                                                 |
| `async_mode`                  | boolean | `false` | Return immediately with `job_id`                                                                     |
| `max_rows`                    | integer | -       | Process only first N items (dry run)                                                                 |
| `source_activity_id`          | string  | -       | Resume from previous job to process remaining items                                                  |
| `reextract_from_activity_id`  | string  | -       | Re-extract from stored research in a previous activity, with optional prompt/schema/feedback changes |
| `include_source_explanations` | boolean | `true`  | Add explanation for each field value. Public jobs keep this enabled                                  |
| `include_service_usage`       | boolean | `false` | Include detailed cost, token, and call metrics when the job completes                                |
| `capture_source_artifacts`    | boolean | `false` | Preserve durable source copies for audit trails                                                      |
| `host_media`                  | boolean | `false` | Copy returned image/document URLs into Rastro-hosted storage                                         |
| `strict_hosted_media`         | boolean | `false` | Clear media/document outputs unless hosting succeeds                                                 |
| `webhook_url`                 | string  | -       | HTTPS URL to receive a POST when the job completes (see [Webhooks](#webhooks))                       |

***

## Large Jobs And File Uploads

Inline JSON requests are capped at 1000 items and 10 MB. For larger jobs, send `multipart/form-data` with a small `request_json` field and exactly one `items_file` upload.

```bash theme={null}
curl -X POST "https://catalogapi.rastro.ai/api/public/enrich" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F 'request_json={"output_schema":[{"name":"manufacturer","type":"string","description":"Brand or manufacturer"}],"speed":"deep","async_mode":true}' \
  -F "items_file=@items.json;type=application/json"
```

`items_file` must be either a JSON array of item objects or an object with an `items` array. Do not send `items_storage_url`; that field is internal.

***

## Output Schema

Define fields to extract. Each field needs a `name`, `type`, and `description`.

```json theme={null}
{
  "output_schema": [
    {"name": "material", "type": "string", "description": "Material composition"},
    {"name": "weight_kg", "type": "number", "description": "Weight in kilograms", "unit": "kg"},
    {"name": "certifications", "type": "array", "description": "Safety certifications"}
  ]
}
```

### Field Options

| Option               | Type    | Description                                                       |
| -------------------- | ------- | ----------------------------------------------------------------- |
| `name`               | string  | Field name (required)                                             |
| `type`               | string  | `string`, `number`, `integer`, `boolean`, `array`                 |
| `description`        | string  | What to extract (required)                                        |
| `unit`               | string  | Units for numbers (e.g., `"kg"`, `"mm"`)                          |
| `enum`               | array   | Constrain to specific values                                      |
| `sample_values`      | array   | Example values to guide extraction                                |
| `array_element_type` | string  | For arrays: `string`, `number`, `image_url`                       |
| `items_enum`         | array   | For array-type fields, constrains array items to specific values  |
| `required`           | boolean | Marks whether this field is required in the output                |
| `merge`              | boolean | Merge enriched values with existing values instead of overwriting |

***

## Response

```json theme={null}
{
  "job_id": "abc123-def456-...",
  "results": [{
    "original_data": {"part_number": "6205-2RS", "name": "Deep Groove Ball Bearing"},
    "after_data": {
      "part_number": "6205-2RS",
      "name": "Deep Groove Ball Bearing",
      "bore_diameter": "25 mm",
      "outer_diameter": "52 mm",
      "sources": {
        "bore_diameter": ["https://skf.com/products/bearings/6205-2RS"],
        "outer_diameter": ["https://skf.com/products/bearings/6205-2RS"]
      },
      "source_explanations": {
        "bore_diameter": "Found on manufacturer product page",
        "outer_diameter": "Found on manufacturer product page"
      }
    },
    "all_sources": ["https://skf.com/products/bearings/6205-2RS"]
  }],
  "total_items": 1,
  "successful": 1,
  "credits_used": 1,
  "status": "completed"
}
```

### Response Fields

| Field                    | Type    | Description                                                       |
| ------------------------ | ------- | ----------------------------------------------------------------- |
| `job_id`                 | string  | Job ID for tracking                                               |
| `results`                | array   | Enriched items (empty if `async_mode=true`)                       |
| `total_items`            | integer | Total items submitted                                             |
| `total_rows`             | integer | Total items before `max_rows` limit                               |
| `successful`             | integer | Successfully enriched items                                       |
| `credits_used`           | integer | Credits used (1 per item)                                         |
| `status`                 | string  | `"running"`, `"completed"`, or `"failed"`                         |
| `completed_items`        | integer | Items with results available so far. Present on polling responses |
| `pricing_estimates`      | object  | Pricing estimate details when available                           |
| `knowledge_base_sources` | object  | Source IDs to hosted document URLs when a knowledge base is used  |

### Result Item Fields

| Field                             | Type   | Description                                                                                                                                                             |
| --------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `original_data`                   | object | Input data                                                                                                                                                              |
| `after_data`                      | object | Complete enriched record. Contains original fields, enriched values, `sources` (per-field URL citations), and `source_explanations` (per-field derivation explanations) |
| `all_sources`                     | array  | Deduplicated list of all URLs used across all fields                                                                                                                    |
| `error`                           | string | Error message if failed                                                                                                                                                 |
| `category_id`                     | string | Predicted category (if taxonomy enabled)                                                                                                                                |
| `category_path`                   | string | Full path like `"Bearings > Ball Bearings"`                                                                                                                             |
| `taxonomy_attributes`             | object | Category-specific attributes                                                                                                                                            |
| `taxonomy_attribute_explanations` | object | Per-attribute explanations of how taxonomy values were derived                                                                                                          |
| `review_info`                     | object | AI reasoning and flags (see below)                                                                                                                                      |
| `low_confidence_candidates`       | array  | Plausible but non-canonical candidates when enabled                                                                                                                     |
| `low_confidence_fields`           | array  | Fields that should be highlighted as low confidence                                                                                                                     |

***

## GET /public/enrich/{job_id}

Poll enrichment job status and retrieve results. Results are returned **progressively** — partial results are available while the job is still running, as each batch of items completes processing.

### Query Parameters

| Parameter   | Type    | Default | Description             |
| ----------- | ------- | ------- | ----------------------- |
| `page`      | integer | `1`     | Page number (1-indexed) |
| `page_size` | integer | `1000`  | Results per page        |

<CodeGroup>
  ```python Python theme={null}
  # Basic poll
  response = requests.get(
      f"https://catalogapi.rastro.ai/api/public/enrich/{job_id}",
      headers={"Authorization": "Bearer YOUR_API_KEY"}
  )

  # With pagination
  response = requests.get(
      f"https://catalogapi.rastro.ai/api/public/enrich/{job_id}",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      params={"page": 1, "page_size": 50}
  )
  ```

  ```bash cURL theme={null}
  # Basic poll
  curl "https://catalogapi.rastro.ai/api/public/enrich/{job_id}" \
    -H "Authorization: Bearer YOUR_API_KEY"

  # With pagination
  curl "https://catalogapi.rastro.ai/api/public/enrich/{job_id}?page=1&page_size=50" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  // Basic poll
  const response = await fetch(`https://catalogapi.rastro.ai/api/public/enrich/${jobId}`, {
    headers: { "Authorization": "Bearer YOUR_API_KEY" }
  });

  // With pagination
  const response = await fetch(
    `https://catalogapi.rastro.ai/api/public/enrich/${jobId}?page=1&page_size=50`,
    { headers: { "Authorization": "Bearer YOUR_API_KEY" } }
  );
  ```
</CodeGroup>

### Poll Response

```json theme={null}
{
  "job_id": "abc123-def456-...",
  "status": "running",
  "results": [
    {
      "original_data": {"part_number": "6205-2RS"},
      "after_data": {
        "part_number": "6205-2RS",
        "bore_diameter": "25 mm",
        "sources": {
          "bore_diameter": ["https://skf.com/products/bearings/6205-2RS"]
        }
      },
      "all_sources": ["https://skf.com/products/bearings/6205-2RS"]
    }
  ],
  "total_items": 500,
  "completed_items": 200,
  "successful": 0,
  "credits_used": 0,
  "page": 1,
  "page_size": 50,
  "total_pages": 4
}
```

### Poll Response Fields

| Field             | Type    | Description                                                 |
| ----------------- | ------- | ----------------------------------------------------------- |
| `job_id`          | string  | Job ID                                                      |
| `status`          | string  | Current status (see below)                                  |
| `results`         | array   | Enriched items for the current page                         |
| `total_items`     | integer | Total items submitted                                       |
| `completed_items` | integer | Items with results available so far (grows while `running`) |
| `successful`      | integer | Finalized success count (set when job finishes)             |
| `credits_used`    | integer | Credits charged (`0` while `running`)                       |
| `page`            | integer | Current page number                                         |
| `page_size`       | integer | Results per page                                            |
| `total_pages`     | integer | Total pages based on `completed_items`                      |
| `service_usage`   | object  | Cost details (only present when job finishes)               |

<Note>
  While `status` is `running`, `completed_items` reflects how many items have finished so far. Use `completed_items` and `total_items` to show progress. `credits_used` remains `0` until the job finishes.
</Note>

### Status Values

| Status      | Description                     | Results available?                           |
| ----------- | ------------------------------- | -------------------------------------------- |
| `running`   | Job is still processing         | Yes — partial results from completed batches |
| `completed` | Job finished, all results ready | Yes — all results                            |
| `failed`    | Job failed or was cancelled     | Yes — partial results from completed batches |

<Note>
  Cancelled jobs are reported as `failed`. Partial results and credits for completed items are preserved.
</Note>

***

## Source Citations

Each result includes `all_sources` — the URLs used during enrichment.

```json theme={null}
{
  "all_sources": [
    "https://skf.com/products/bearings/6205-2RS",
    "https://mcmaster.com/6205-2RS"
  ]
}
```

When `web_search` is `false`, the AI uses only the input data (`INPUT_DATA`) to derive field values.

***

## AI Transparency

Every result includes `review_info` with AI reasoning:

```json theme={null}
{
  "review_info": {
    "reasoning": "Found specs on manufacturer website, cross-referenced with distributor",
    "flags": ["verify_tolerance_class"],
    "field_issues": [
      {"field": "tolerance", "severity": "warning", "message": "Value not found in sources"}
    ],
    "flag_record": true
  }
}
```

| Field          | Type    | Description                                                                                |
| -------------- | ------- | ------------------------------------------------------------------------------------------ |
| `reasoning`    | string  | AI explanation of how values were extracted                                                |
| `flags`        | array   | General flags or warnings about the extraction                                             |
| `field_issues` | array   | Per-field issues with `field`, `severity` (error/warning/info), `message`, and `validator` |
| `flag_record`  | boolean | Whether this record needs human attention                                                  |

***

## Webhooks

Instead of polling `GET /public/enrich/{job_id}`, you can provide a `webhook_url` to receive a POST when the job finishes. The URL **must use HTTPS**.

```json theme={null}
{
  "items": [...],
  "output_schema": [...],
  "async_mode": true,
  "webhook_url": "https://yourserver.com/hooks/enrich"
}
```

### Webhook Payload

When the job completes, we POST a JSON body to your URL:

```json theme={null}
{
  "job_id": "abc123-def456-...",
  "status": "completed",
  "successful": 150,
  "failed": 5,
  "total": 155,
  "credits_used": 150
}
```

| Field          | Type    | Description                                                  |
| -------------- | ------- | ------------------------------------------------------------ |
| `job_id`       | string  | Use with `GET /public/enrich/{job_id}` to fetch full results |
| `status`       | string  | Always `"completed"`                                         |
| `successful`   | integer | Items enriched successfully                                  |
| `failed`       | integer | Items that failed                                            |
| `total`        | integer | `successful + failed`                                        |
| `credits_used` | integer | Credits charged                                              |

<Note>
  Webhook delivery is best-effort with a single attempt and a 30-second timeout. If delivery fails the job is unaffected — use polling as a fallback.
</Note>

***

## Job Management

### GET /public/enrich/jobs

List enrichment jobs for your organization, with optional status filtering and pagination.

#### Query Parameters

| Parameter | Type    | Default | Description                                                     |
| --------- | ------- | ------- | --------------------------------------------------------------- |
| `status`  | string  | (all)   | Filter by status: `running`, `completed`, `failed`, `cancelled` |
| `limit`   | integer | `20`    | Results per page (1–100)                                        |
| `offset`  | integer | `0`     | Pagination offset                                               |

<CodeGroup>
  ```python Python theme={null}
  import requests

  # List running jobs
  response = requests.get(
      "https://catalogapi.rastro.ai/api/public/enrich/jobs",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
      params={"status": "running"}
  )
  jobs = response.json()
  ```

  ```bash cURL theme={null}
  curl "https://catalogapi.rastro.ai/api/public/enrich/jobs?status=running" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch(
    "https://catalogapi.rastro.ai/api/public/enrich/jobs?status=running",
    { headers: { "Authorization": "Bearer YOUR_API_KEY" } }
  );
  const data = await response.json();
  ```
</CodeGroup>

#### Response

```json theme={null}
{
  "jobs": [
    {
      "job_id": "abc123-def456-...",
      "status": "running",
      "total_items": 500,
      "completed_items": 200,
      "failed_items": 3,
      "created_at": "2026-02-11T10:00:00+00:00",
      "started_at": "2026-02-11T10:00:01+00:00",
      "finished_at": null
    }
  ],
  "total": 12
}
```

| Field   | Type    | Description                    |
| ------- | ------- | ------------------------------ |
| `jobs`  | array   | List of job summaries          |
| `total` | integer | Total jobs matching the filter |

Each job object:

| Field             | Type    | Description                                      |
| ----------------- | ------- | ------------------------------------------------ |
| `job_id`          | string  | Job ID (use with other endpoints)                |
| `status`          | string  | `running`, `completed`, `failed`, or `cancelled` |
| `total_items`     | integer | Items submitted                                  |
| `completed_items` | integer | Items processed so far                           |
| `failed_items`    | integer | Items that failed                                |
| `created_at`      | string  | ISO 8601 timestamp                               |
| `started_at`      | string  | ISO 8601 timestamp (null if not yet started)     |
| `finished_at`     | string  | ISO 8601 timestamp (null if still running)       |

***

### POST /public/enrich/{job_id}/cancel

Cancel a running enrichment job. Items already processed are kept and credits are charged only for completed items.

<CodeGroup>
  ```python Python theme={null}
  import requests

  response = requests.post(
      f"https://catalogapi.rastro.ai/api/public/enrich/{job_id}/cancel",
      headers={"Authorization": "Bearer YOUR_API_KEY"}
  )
  result = response.json()
  print(f"Cancelled — {result['completed_items']} items kept, {result['credits_used']} credits charged")
  ```

  ```bash cURL theme={null}
  curl -X POST "https://catalogapi.rastro.ai/api/public/enrich/{job_id}/cancel" \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch(
    `https://catalogapi.rastro.ai/api/public/enrich/${jobId}/cancel`,
    { method: "POST", headers: { "Authorization": "Bearer YOUR_API_KEY" } }
  );
  const result = await response.json();
  ```
</CodeGroup>

#### Response

```json theme={null}
{
  "success": true,
  "message": "Activity abc123-def456 cancelled",
  "completed_items": 200,
  "credits_used": 200
}
```

| Field             | Type    | Description                             |
| ----------------- | ------- | --------------------------------------- |
| `success`         | boolean | Whether cancellation succeeded          |
| `message`         | string  | Human-readable status                   |
| `completed_items` | integer | Items that finished before cancellation |
| `credits_used`    | integer | Credits charged for completed items     |

<Note>
  Cancellation is intended for active jobs. Jobs that are already cancelled return a successful cancelled response; completed jobs may return an error.
</Note>

***

### POST /public/enrich/{job_id}/to-catalog

Create a new catalog from an enrichment run.

```bash theme={null}
curl -X POST "https://catalogapi.rastro.ai/api/public/enrich/{job_id}/to-catalog" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Enriched Products"}'
```

Use this when you ran enrichment first and want to persist the finished results as a new catalog.

***

## Templates, Inference, And Judging

| Endpoint                                         | Description                                                                                                  |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| `GET /public/enrichment-templates`               | List enabled enrichment templates available to your organization                                             |
| `GET /public/enrichment-templates/{template_id}` | Get a template. Supports `include_taxonomy=true` and `taxonomy_format=expanded` or `taxonomy_format=compact` |
| `POST /public/infer-enrichment`                  | Infer catalog schema, taxonomy, and web enrichment fields from sample items                                  |
| `POST /public/infer-schema`                      | Upload a CSV/Excel file and infer schema plus enrichment config                                              |
| `POST /public/judge`                             | Judge rows against a catalog schema or inline schema. Supports per-row image URLs                            |

Example inference request:

```bash theme={null}
curl -X POST "https://catalogapi.rastro.ai/api/public/infer-enrichment" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"Industrial bearings catalog","items":[{"sku":"6205-2RS","name":"Deep Groove Ball Bearing"}]}'
```

Example judge request:

```bash theme={null}
curl -X POST "https://catalogapi.rastro.ai/api/public/judge" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"catalog_id":"cat_123","rows":[{"sku":"A1","title":"Product A"}],"max_rows":50}'
```
