SAGEX3 AI INTEGRATION
Give your AI agent deep expertise in Sage X3 ERP. This skill covers the full GraphQL API — master data, transactions, reporting, and patterns for building AI-powered dashboards on the edge.
LIVE v1.0 ERP GraphQL Edge AI
npx skills add imbilawork/2nth-skills@sagex3-ai
01

OVERVIEW

Sage X3 (formerly Sage Enterprise Management) is a mid-market ERP powering manufacturing, distribution, and services companies. Modern instances expose a GraphQL API via the Syracuse web server using the Yoga GraphQL engine.

This skill gives AI agents the knowledge to query, report on, and integrate with Sage X3 — without hallucinating endpoints or field names.

API Type
GRAPHQL
Auth
BASIC
Pagination
RELAY
Domains
5+
02

ARCHITECTURE

The recommended integration pattern uses a Cloudflare Worker as a proxy — this avoids CORS, secures credentials at the edge, and enables AI analysis via Workers AI.

User / Dashboard
Cloudflare Worker
Proxy + AI
Sage X3
GraphQL API

Endpoint Pattern

https://<host>:<port>/<folder>/api

Authentication

Authorization: Basic base64(USERNAME:PASSWORD)
Security

Never expose Sage X3 credentials in client-side code. Use a server-side proxy with secrets stored via wrangler secret put or environment variables.

03

CAPABILITIES

What your agent can do with this skill installed:

  • Query master data — customers, suppliers, products, stock sites
  • Pull transactions — sales orders, purchase orders, invoices, deliveries
  • Check inventory — stock levels, reorder alerts, warehouse positions
  • Generate reports — revenue by customer, aged debtors, sales trends
  • Introspect the schema — discover what's available on any Sage X3 instance
  • Build dashboards — structure data for Chart.js, tables, and KPI cards
  • Natural language queries — translate questions into GraphQL
  • Deploy to edge — Cloudflare Workers proxy with AI analysis
04

SCHEMA MAP

Sage X3 organizes its GraphQL API by business domain. Each domain contains entities that follow the Relay pagination pattern.

x3MasterData — Master data ├── customer — Business partners (customers) ├── supplier — Business partners (suppliers) ├── product — Product catalog └── stockSite — Warehouses / sites x3Sales — Sales domain ├── salesOrder — Sales orders ├── salesInvoice — Sales invoices └── salesDelivery — Delivery notes x3Purchasing — Purchasing domain ├── purchaseOrder — Purchase orders └── purchaseReceipt — Goods receipt x3Stock — Inventory domain ├── stockChange — Stock movements └── stockCount — Stock counts x3Accounting — Financial domain ├── journalEntry — Journal entries └── generalLedger — GL accounts
Instance-specific

Schema varies by installation — modules, custom fields, and endpoints differ. Always introspect first with __schema queries.

05

QUERY PATTERNS

Relay Pagination

All list queries use edges / node with cursor-based pagination:

query {
  x3MasterData {
    customer {
      query(first: 10, after: "cursor") {
        edges {
          node {
            code {
              code
              companyName1
              country { code countryName }
              currency { code }
            }
          }
        }
        pageInfo {
          hasNextPage
          endCursor
        }
      }
    }
  }
}

Customer Master Data

query Customers {
  x3MasterData {
    customer {
      query(first: 50) {
        edges {
          node {
            code {
              code
              companyName1
              country { code countryName }
              currency { code localizedDescription }
              isCustomer
              isSupplier
              creditLimit
              paymentTerms { code localizedDescription }
            }
          }
        }
      }
    }
  }
}

Sales Orders

query SalesOrders {
  x3Sales {
    salesOrder {
      query(first: 25) {
        edges {
          node {
            code {
              orderNumber
              orderDate
              customer { code companyName1 }
              totalAmount
              status
              lines {
                product { code localizedDescription1 }
                quantity
                unitPrice
                lineAmount
              }
            }
          }
        }
      }
    }
  }
}

OData-style Filtering

# Active South African customers
query(first: 50, filter: "country.code eq 'ZA' and isCustomer eq true")

# Orders this year
query(first: 100, filter: "orderDate ge '2026-01-01'")
OperatorMeaningExample
eqEqualsstatus eq 'Active'
neNot equalscountry.code ne 'ZA'
gt / geGreater than (or equal)totalAmount gt 10000
lt / leLess than (or equal)orderDate lt '2026-03-01'
contains()Substring matchcontains(companyName1, 'Umbrella')
and / orLogicalisCustomer eq true and isSupplier eq true
06

REPORTING PATTERNS

Sage X3 GraphQL doesn't support aggregation — fetch data and aggregate client-side.

Revenue by Customer

query RevenueReport {
  x3Sales {
    salesOrder {
      query(first: 1000, filter: "orderDate ge '2026-01-01'") {
        edges {
          node {
            code {
              customer { code companyName1 }
              totalAmount
              currency { code }
              orderDate
            }
          }
        }
      }
    }
  }
}
// Then group by customer.code, sum totalAmount

Aged Debtors

query AgedDebtors {
  x3Sales {
    salesInvoice {
      query(first: 500, filter: "outstandingAmount gt 0") {
        edges {
          node {
            code {
              invoiceNumber
              invoiceDate
              dueDate
              customer { code companyName1 }
              totalAmount
              outstandingAmount
            }
          }
        }
      }
    }
  }
}
// Age buckets: Current, 30d, 60d, 90d+

Inventory Alerts

Fetch stock levels and filter where quantityOnHand < reorderPoint.

07

AI INTEGRATION

The power pattern: natural language in, formatted report out.

User Question
LLM generates
GraphQL
Execute on
Sage X3
LLM analyzes
results
Report

Cloudflare Worker Proxy

async function handleGraphQL(request, env) {
  const { query, variables } = await request.json();
  const credentials = btoa(
    `${env.SAGE_X3_USERNAME}:${env.SAGE_X3_PASSWORD}`
  );

  const response = await fetch(env.SAGE_X3_ENDPOINT, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Basic ${credentials}`,
    },
    body: JSON.stringify({ query, variables }),
  });

  return new Response(response.body, {
    status: response.status,
    headers: { 'Content-Type': 'application/json' },
  });
}

Natural Language System Prompt

You are a Sage X3 GraphQL expert. Given a natural
language question, generate the appropriate GraphQL query.
The API uses Relay pagination (edges/node) with domains:
x3MasterData, x3Sales, x3Purchasing, x3Stock, x3Accounting.
Always include the `first` parameter for pagination.
Respond with ONLY the GraphQL query.
08

INSTALL

Works with Claude Code, Cursor, Windsurf, Cline, and 30+ other AI agents:

npx skills add imbilawork/2nth-skills@sagex3-ai

Or install globally with no prompts:

npx skills add imbilawork/2nth-skills@sagex3-ai -g -y

The skill is loaded automatically when your agent works on Sage X3 related tasks.

09

GOTCHAS

IssueDetail
Fields under codeAll data lives inside node.code, not directly on node
Pagination requiredAlways pass first; omitting it may return 0 results
CORS blockedBrowser requests fail — use a server-side proxy
Schema variesAlways introspect; installed modules and custom fields differ
No aggregationGraphQL doesn't support GROUP BY — aggregate client-side
Date formatISO 8601 in filters: '2026-01-01'
Self-signed certsDev instances may need NODE_TLS_REJECT_UNAUTHORIZED=0
Rate limitsSyracuse has connection limits — batch queries where possible