Generic ERP / PIM

Add AI-powered AAS extraction to any system that holds part records and stores datasheet PDFs as attachments — Microsoft Dynamics, Oracle, Infor, custom PIMs, etc.

Audience: Integration architects evaluating AAS Studio for a system not on our named list.

Topology

  1. Your ERP triggers a workflow when a part is created or its datasheet is updated
  2. Your integration layer (Logic Apps, n8n, Make, custom service) downloads the PDF
  3. POST to AAS Studio /api/v1/extract
  4. Map the structured result onto your ERP's part metadata table
  5. Optionally store the AAS Studio extraction id as a part attribute for traceability — fetch the audit-replay anytime via /api/v1/extractions/{id}

TypeScript

import { AasStudioClient } from '@aas-studio/sdk'

const aas = new AasStudioClient({ apiKey: process.env.AAS_STUDIO_KEY! })

// Generic n8n / Logic Apps / serverless function pattern
export async function handler(event: { partId: string; pdfUrl: string }) {
  // 1. Fetch the PDF from your ERP attachment URL
  const pdf = await fetch(event.pdfUrl).then(r => r.arrayBuffer())

  // 2. Extract
  const { result } = await aas.extract({
    file: new Uint8Array(pdf),
    fileName: `${event.partId}.pdf`,
    idPrefix: `urn:acme:erp:${event.partId}`,
  })

  // 3. Flatten onto your part metadata
  const flat: Record<string, string> = {}
  for (const sm of result.submodels) {
    for (const el of sm.elements) {
      if (el.value) flat[`${sm.idShort}.${el.idShort}`] = el.value
    }
  }

  // 4. Push into your ERP
  await fetch(process.env.ERP_PART_API + '/' + event.partId, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${process.env.ERP_TOKEN}` },
    body: JSON.stringify({ metadata: flat, aasExtractionId: result.assetId }),
  })
}

Install: npm install @aas-studio/sdk

Python

import os
import requests
from aas_studio import AasStudioClient

aas = AasStudioClient(api_key=os.environ["AAS_STUDIO_KEY"])

def handler(event):
    pdf_bytes = requests.get(event["pdfUrl"]).content

    response = aas.extract(
        pdf_bytes,
        file_name=f"{event['partId']}.pdf",
        id_prefix=f"urn:acme:erp:{event['partId']}",
    )
    result = response["result"]

    flat = {}
    for sm in result["submodels"]:
        for el in sm["elements"]:
            if el.get("value"):
                flat[f"{sm['idShort']}.{el['idShort']}"] = el["value"]

    requests.patch(
        f"{os.environ['ERP_PART_API']}/{event['partId']}",
        headers={"Authorization": f"Bearer {os.environ['ERP_TOKEN']}"},
        json={"metadata": flat, "aasExtractionId": result["assetId"]},
    )

Install: pip install aas-studio

Common pitfalls

  • For high-volume ingest, batch by spinning up a worker pool. The TypeScript SDK is async — wrap in p-limit or your queue runner. The Python SDK is synchronous — use a ThreadPoolExecutor or asyncio.to_thread.
  • Idempotency: AAS Studio extractions aren't deterministic at the LLM level. If your workflow can re-trigger (e.g. PDF re-upload), guard with a hash check on the PDF before re-extracting — same SHA-256 → skip and reuse the saved /api/v1/extractions entry.
  • Authority context: when you flatten the result for your ERP, low-confidence elements (tier !== "high") should NOT silently overwrite human-curated values. Either gate writes by confidence, or write to a "candidate" field and surface a review UI.
  • For multi-tenant ERPs, give each tenant its own AAS Studio API key — quota lives at the key level, not the workspace level. One tenant blowing through the limit shouldn't affect others.

References

All integration guidesTry AAS Studio free

Command palette

Navigate + run actions