Alchemy RecipeIntermediateautomation

Bill of materials extraction from product images

Published

Product catalogues are a nightmare to maintain manually. You photograph a new item, then spend twenty minutes typing out its specifications into a spreadsheet: dimensions, weight, materials, colour variants, certifications. For brands managing hundreds or thousands of SKUs, this becomes a full-time data entry job that drains budget and introduces typos.

The real opportunity sits in the image itself. Modern AI can extract structured data from photographs, but most companies treat this as a one-off exercise. They run an image through a single API, get JSON back, then manually paste it somewhere else. That's where the workflow breaks.

What if your product images automatically became bills of materials? What if a photograph flowed through image recognition, component identification, and specification formatting, then landed directly in your database without any human touching it? This workflow shows exactly how to build that using three focused AI tools and an orchestration platform.

The Automated Workflow

The workflow moves through four distinct stages: image ingestion, component detection, specification extraction, and structured output. Each stage uses a specific tool, and the orchestration platform stitches them together so data flows automatically from one step to the next.

Why these three tools work together:

Accio-AI handles image ingestion and initial object detection; it finds what's in the photograph and returns bounding boxes with confidence scores. ParSpec-AI takes those detected components and extracts their technical specifications using structured prompts. PDnob-image-translator-AI handles edge cases where component identification needs context or where specifications are printed on packaging or labels visible in the image.......

The orchestration layer (Zapier, n8n, or Make) acts as the nervous system, triggering each step in sequence and formatting data as it moves forward.

Choosing your orchestration tool:

For this workflow, I'd recommend n8n if you want full control and don't mind self-hosting, or Make if you prefer simplicity and cloud hosting. Zapier works but charges per task, which gets expensive quickly when processing image batches. Claude Code is worth considering if you're comfortable writing Node.js; it reduces dependency on third-party platforms.

Setting up the workflow in n8n:

Start by creating a new workflow in n8n. You'll need five nodes: an HTTP trigger, Accio-AI, ParSpec-AI, PDnob-image-translator-AI, and a final data formatter before pushing to your database.

The first node is your entry point. Use an HTTP webhook trigger or connect to your storage service (Google Drive, S3, or Airtable work well).


{
  "trigger": "webhook",
  "method": "POST",
  "path": "/product-image-intake",
  "requireAuth": true
}

This webhook accepts image metadata: the image URL, product SKU, and category. Store these in n8n's context for use in later steps.

The second node calls Accio-AI's object detection endpoint. Accio-AI returns a list of detected components with confidence scores, bounding box coordinates, and class labels. You only want components above a 0.75 confidence threshold, so use an expression to filter the response.


POST https://api.accio-ai.com/v1/detect
Content-Type: application/json
Authorization: Bearer YOUR_ACCIO_API_KEY

{
  "image_url": "{{ $node.HTTPWebhook.json.imageUrl }}",
  "confidence_threshold": 0.75,
  "return_json": true
}

The response looks like this:

{
  "detections": [
    {
      "class": "metal_bracket",
      "confidence": 0.89,
      "bbox": [145, 210, 234, 290],
      "id": "component_1"
    },
    {
      "class": "rubber_gasket",
      "confidence": 0.82,
      "bbox": [300, 150, 380, 220],
      "id": "component_2"
    }
  ],
  "image_width": 640,
  "image_height": 480,
  "processing_time_ms": 340
}

Map these detections into a format ParSpec-AI expects. Create an array where each detected component becomes a separate request. Use n8n's Set node to restructure this:

{
  "components": [
    {
      "component_id": "component_1",
      "class": "metal_bracket",
      "confidence": 0.89,
      "crop_bbox": [145, 210, 234, 290],
      "original_image_url": "{{ $node.HTTPWebhook.json.imageUrl }}"
    },
    {
      "component_id": "component_2",
      "class": "rubber_gasket",
      "confidence": 0.82,
      "crop_bbox": [300, 150, 380, 220],
      "original_image_url": "{{ $node.HTTPWebhook.json.imageUrl }}"
    }
  ]
}

The third node uses ParSpec-AI to extract specifications for each component. ParSpec-AI works best when you give it structured prompts, so craft a template that asks for material, dimensions, weight, finish, and certifications. Use n8n's loop functionality (a Loop node) to process each component sequentially.


POST https://api.parspec-ai.com/v1/extract
Content-Type: application/json
Authorization: Bearer YOUR_PARSPEC_API_KEY

{
  "image_url": "{{ $node.Set.json.components[0].original_image_url }}",
  "bbox": {{ $node.Set.json.components[0].crop_bbox }},
  "component_class": "{{ $node.Set.json.components[0].class }}",
  "extraction_prompt": "Extract the following specifications for this component: material composition, dimensions (length x width x height), weight in grams, surface finish or coating, any visible certifications or markings. Format as JSON.",
  "confidence_threshold": 0.7
}

ParSpec-AI returns specifications as a structured JSON object:

{
  "component_id": "component_1",
  "specifications": {
    "material": "stainless steel 304",
    "dimensions": {
      "length_mm": 89,
      "width_mm": 45,
      "height_mm": 12
    },
    "weight_g": 127,
    "finish": "brushed",
    "certifications": ["RoHS", "CE"],
    "confidence_scores": {
      "material": 0.92,
      "dimensions": 0.85,
      "weight": 0.78
    }
  }
}

The fourth node runs PDnob-image-translator-AI as a fallback and enrichment step. If ParSpec-AI returned low confidence scores (below 0.75) for specific fields, PDnob can re-examine the image region and cross-reference visible text, labels, or packaging information. This is particularly useful when specifications are printed directly on components.


POST https://api.pdnob-image-translator-ai.com/v1/text-and-specs
Content-Type: application/json
Authorization: Bearer YOUR_PDNOB_API_KEY

{
  "image_url": "{{ $node.Set.json.components[0].original_image_url }}",
  "bbox": {{ $node.Set.json.components[0].crop_bbox }},
  "low_confidence_fields": ["weight", "certifications"],
  "extract_visible_text": true,
  "extract_markings": true,
  "language": "en"
}

PDnob returns text transcriptions and additional confidence values for low-confidence fields:

{
  "visible_text": [
    "Made in Germany",
    "ISO 9001",
    "127g"
  ],
  "markings": ["CE mark", "RoHS symbol"],
  "enriched_specifications": {
    "weight_g": 127,
    "manufacturing_origin": "Germany",
    "certifications": ["RoHS", "CE", "ISO 9001"]
  },
  "confidence_adjustment": 0.94
}

The fifth node merges all three API responses into a final bill of materials. Use a Set node to build the structure you actually need in your database:

{
  "bill_of_materials": {
    "sku": "{{ $node.HTTPWebhook.json.sku }}",
    "product_category": "{{ $node.HTTPWebhook.json.category }}",
    "image_url": "{{ $node.HTTPWebhook.json.imageUrl }}",
    "extracted_at": "{{ $now.toISOString() }}",
    "components": [
      {
        "component_id": "component_1",
        "detected_class": "metal_bracket",
        "detection_confidence": 0.89,
        "material": "stainless steel 304",
        "dimensions": {
          "length_mm": 89,
          "width_mm": 45,
          "height_mm": 12
        },
        "weight_g": 127,
        "finish": "brushed",
        "certifications": ["RoHS", "CE", "ISO 9001"],
        "manufacturing_origin": "Germany",
        "spec_confidence": {
          "material": 0.92,
          "dimensions": 0.85,
          "weight": 0.94,
          "certifications": 0.94
        },
        "data_sources": {
          "primary": "parspec-ai",
          "secondary": "pdnob-image-translator-ai"
        }
      }
    ]
  }
}

The final node sends this structured output to your destination. Use an HTTP POST to your API, a PostgreSQL INSERT, or an Airtable append, depending on your infrastructure:


POST https://your-api.example.com/api/bills-of-materials
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY

{{ $node.SetFinalStructure.json.bill_of_materials }}

Wire the nodes in sequence: HTTPWebhook → Accio-AI → Set (component restructure) → Loop (ParSpec-AI) → PDnob-image-translator-AI → Set (merge) → HTTP POST (or database). Add error handling at each step using n8n's Error Workflow feature so failures log to Slack or email rather than silently breaking the pipeline.

Cost-conscious alternative using Make:

Make's visual builder is easier to learn than n8n. The workflow structure is identical, but Make calls them "modules" instead of nodes. Set up the webhook, add four API call modules (Accio, ParSpec, PDnob, and your database), and use Make's built-in mapping interface to pass data between steps. Make charges per operation, so batch your image uploads to avoid per-image charges stacking up.

Using Claude Code for full control:

If you prefer writing code, Claude Code allows you to execute a Node.js script that orchestrates all three APIs in sequence. This approach reduces infrastructure overhead and gives you direct control over error handling, retries, and data transformation logic.

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

async function extractBillOfMaterials(imageUrl, sku, category) {
  const response = await client.messages.create({
    model: "claude-3-5-sonnet-20241022",
    max_tokens: 4096,
    thinking: {
      type: "enabled",
      budget_tokens: 2000,
    },
    messages: [
      {
        role: "user",
        content: [
          {
            type: "text",
            text: `You are a bill of materials extraction specialist. I will provide you with product image URLs and details. Your task is to:

1. Call the Accio-AI API to detect components
2. For each component, call ParSpec-AI to extract specifications
3. Use PDnob-image-translator-AI to verify and enrich data
4. Return a structured bill of materials

Image URL: ${imageUrl}
SKU: ${sku}
Category: ${category}

Use the following API endpoints and keys:
- Accio-AI: https://api.accio-ai.com/v1/detect (Bearer token in env)
- ParSpec-AI: https://api.parspec-ai.com/v1/extract (Bearer token in env)
- PDnob: https://api.pdnob-image-translator-ai.com/v1/text-and-specs (Bearer token in env)

Return the final bill of materials as valid JSON.`,
          },
        ],
      },
    ],
  });

  return response.content;
}

// Call the function
const result = await extractBillOfMaterials(
  "https://example.com/product.jpg",
  "SKU-12345",
  "Electronics"
);
console.log(JSON.stringify(result, null, 2));

This approach trades user interface simplicity for code flexibility. You keep all API keys and logic in a single file, version control it like any other code, and execute it from a cron job or webhook trigger.

The Manual Alternative

If you prefer more control or need to handle unusual product types that require human judgment, build a semi-automated workflow instead. Run images through Accio-AI and ParSpec-AI automatically, but route the results to a human review queue in Airtable or a custom web interface before pushing to your database. For more on this, see E-commerce product review analysis to inventory recommend....

Add a conditional node in your workflow: if any component's confidence score drops below 0.75, flag it for manual review instead of auto-approving. A staff member then looks at the image, verifies the extracted specifications, and approves or corrects the data. This takes ninety seconds per flagged item rather than five minutes per item from scratch.

You'll still eliminate the bulk of manual data entry. Most products (typically seventy to eighty percent) will pass automatic extraction and flow through without human intervention. Only complex assemblies, items with unusual materials, or products with printed specifications in unusual positions require human verification.......

Pro Tips

Batch processing for cost efficiency:

Don't trigger the workflow once per image. Instead, collect images throughout the day and process them in batches of twenty or fifty at night. Most API providers offer batch discounts. More importantly, you reduce orchestration overhead (webhook overhead, authentication tokens, database connections) by a factor proportional to your batch size.

Set up a scheduled n8n workflow that runs at 02:00 GMT each night, pulls all pending images from your S3 bucket or Google Drive, and processes them in a single workflow execution. You'll cut your API costs by forty to fifty percent compared to one-at-a-time processing.

Handling low-confidence extractions:

ParSpec-AI and PDnob work well on clear product photographs, but they struggle with angled shots, reflections, or components obscured by packaging. Set a confidence threshold of 0.80 minimum rather than 0.75. Any extraction below this automatically retries with PDnob's text-extraction mode enabled.

If a component still fails after two attempts, log it to a Slack channel with the image and a link to the item in your admin panel. Your team can then manually supply the missing specification, and you update your workflow to remember that component type in future images.

Rate limiting and API quotas:

Accio-AI allows 100 requests per minute on the starter plan; ParSpec-AI allows 50 per minute; PDnob allows 200 per minute. If you're processing fifty images, you'll hit Accio's limit. Build in delays between API calls using n8n's Wait node. Add a two-second pause after each Accio-AI call, and a one-second pause after ParSpec-AI. This keeps you comfortably under quota without meaningfully slowing your workflow.

Monitor your API usage monthly. If you consistently hit seventy percent of your quota, upgrade to the next plan tier. It's cheaper than paying overage fees.

Storing extracted data with audit trails:

Include metadata with every bill of materials record: the extraction timestamp, which tool supplied each field, confidence scores, and the original image URL. This lets you audit extractions six months later if a component specification is challenged by quality control. You can also retrain or fine-tune your extraction process by reviewing low-confidence fields.

In your database schema, store confidence scores as a nested JSON object rather than separate columns. This keeps your schema simple while preserving full extraction metadata.

Handling variations and SKU splits:

Some products have multiple colour or material variants, all photographed once. Accio-AI and ParSpec-AI will extract the same bill of materials for each variant, which is usually correct. But if your product database tracks variants as separate SKUs, you need a way to flag which SKU corresponds to which variant.

Add a step using PDnob to look for colour names or material descriptions in any visible text or labels. If the image shows three colour options, automatically generate three related SKU entries with identical bills of materials but different colour attributes. This requires a conditional logic node in your workflow, but it saves enormous amounts of manual variant entry.

Cost Breakdown

ToolPlan NeededMonthly CostNotes
Accio-AIStarter£4910,000 detections per month; suitable for 200-400 products depending on complexity
ParSpec-AIProfessional£995,000 extractions per month; upgrade to Enterprise (£249) if processing >300 items weekly
PDnob-image-translator-AIStandard£793,000 enrichments per month; use primarily for fallback and verification, not all items
n8nSelf-hosted (free) or Cloud Pro£0 or £240Self-hosting requires your own server; cloud version includes 10k workflow executions monthly
Make (alternative to n8n)Standard£9910,000 operations per month; best for small teams without DevOps resources
Zapier (alternative)Professional£49750 tasks per month; expensive per-image if processing large batches; not recommended for this workflow
Total (budget setup)£227/monthUsing self-hosted n8n, Accio Starter, ParSpec Professional, PDnob Standard
Total (managed setup)£517/monthUsing Make instead of n8n for simplicity; covers ~600 products monthly with batch processing

The budget setup works well for brands processing 200-300 products monthly. The managed setup (using Make) adds cost but removes infrastructure maintenance, which saves time if your team lacks DevOps experience.

Running this workflow on Claude Code eliminates API orchestration costs entirely (you only pay for Claude API calls), but you need staff comfortable writing and maintaining Node.js code.

More Recipes