# Design Advice (XML) - api/flow?

**URL:** <https://connective.celigo.com/t/design-advice-xml-api-flow/6231>\
**Category:** Integrator.io\
**Created:** [April 30, 2026, 12:05pm UTC](https://connective.celigo.com/t/design-advice-xml-api-flow/6231 "2026-04-30T12:05:28Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![James\_Mitchell](https://avatars.discourse-cdn.com/v4/letter/j/3be4f8/32.png) [@James\_Mitchell](https://connective.celigo.com/u/James_Mitchell)\
**Post date:** [April 30, 2026, 12:05pm UTC](https://connective.celigo.com/t/design-advice-xml-api-flow/6231/1 "2026-04-30T12:05:28Z")

</div>

First off, I'm very new to the platform, and I'm not entirely sure of it's capabilities, so I need expert advice :).

At a very high level, I need to accept an XML request via an endpoint, query an ERP for data, and respond to that request in XML. I have schemas and sample request/responses.

I guess I'm just wondering what something like this would entail, or if it's even possible.

Any advice, suggestions, or resources is much appreciated.

Thank you in advance.

---

<div class="post-metadata">

**Author:** ![tylerlamparter](https://sea1.discourse-cdn.com/flex001/user_avatar/connective.celigo.com/tylerlamparter/32/9204_2.png) [@tylerlamparter](https://connective.celigo.com/u/tylerlamparter)\
**Post date:** [April 30, 2026, 5:47pm UTC](https://connective.celigo.com/t/design-advice-xml-api-flow/6231/2 "2026-04-30T17:47:36Z")

</div>

It sounds like you need an API since you need to synchronously respond to the system asking for data. Our API builder doesn't support XML, but you can use [JavaScript APIs](https://docs.celigo.com/hc/en-us/articles/360047267771-JavaScript-API-basics) to support this. Here is a sample JavaScript API I made to showcase:

```javascript
import { exports as celigoExports } from 'integrator-api'
// 'exports' is reserved at module scope, so alias it.
// Other namespaces: import { imports, connections } from 'integrator-api'

function handleRequest (options) {
  var rawXml = options.rawBody || ''

  var orderId = extractTag(rawXml, 'OrderId')
  if (!orderId) {
    return {
      statusCode: 400,
      headers: { 'Content-Type': 'application/xml' },
      body: buildFault('ValidationError', 'Missing required <OrderId> element.')
    }
  }

  var record = dummyLookup(orderId)
  if (!record) {
    return {
      statusCode: 404,
      headers: { 'Content-Type': 'application/xml' },
      body: buildFault('NotFound', 'No order found for OrderId ' + orderId + '.')
    }
  }

  var responseXml =
    '<?xml version="1.0" encoding="UTF-8"?>' +
    '<OrderDetails>' +
      '<OrderId>' + escapeXml(record.orderId) + '</OrderId>' +
      '<Customer>' + escapeXml(record.customer) + '</Customer>' +
      '<Status>' + escapeXml(record.status) + '</Status>' +
      '<Total currency="' + escapeXml(record.currency) + '">' + escapeXml(record.total) + '</Total>' +
      '<ShipDate>' + escapeXml(record.shipDate) + '</ShipDate>' +
    '</OrderDetails>'

  return {
    statusCode: 200,
    headers: { 'Content-Type': 'application/xml' },
    body: responseXml
  }
}

function dummyLookup (orderId) {
  // ──────────────────────────────────────────────────────────────────────
  // OPTION A — Saved export (resource lives in the account, referenced by _id)
  //
  // var result = celigoExports.run({ _id: '<savedExportId>' })
  //
  // ──────────────────────────────────────────────────────────────────────
  // OPTION B — Virtual export (defined inline, exists only at runtime)
  // Example below is an HTTP/REST GET against an ERP. Shape varies by
  // adaptorType: HTTPExport, RESTExport, NetSuiteExport, RDBMSExport, etc.
  //
  // var virtualExport = {
  // adaptorType: 'HTTPExport',
  // _connectionId: '<connectionId>',
  // http: {
  // relativeURI: '/orders/' + orderId,
  // method: 'GET',
  // response: { resourcePath: 'data' }
  // }
  // }
  // var result = celigoExports.runVirtual({ export: virtualExport })
  //
  // For paginated results, use celigoExports.runVirtualWithPaging({ export, pagedExportState }).
  // ──────────────────────────────────────────────────────────────────────
  //
  // Both options return roughly: { data: [...], errors: [...] }
  //
  // var row = result && result.data && result.data[0]
  // if (!row) return null
  // return {
  // orderId: row.OrderID,
  // customer: row.CustomerName,
  // status: row.OrderStatus,
  // total: row.OrderTotal,
  // currency: row.CurrencyCode,
  // shipDate: row.ShipDate
  // }

  var fixtures = {
    '123': { orderId: '123', customer: 'Acme Corp', status: 'Shipped', total: '249.99', currency: 'USD', shipDate: '2026-04-28' },
    '456': { orderId: '456', customer: 'Globex Inc', status: 'Processing', total: '1875.00', currency: 'USD', shipDate: '' },
    '789': { orderId: '789', customer: 'Initech LLC', status: 'Backordered', total: '42.50', currency: 'USD', shipDate: '' }
  }
  return fixtures[orderId] || null
}

function extractTag (xml, tagName) {
  var re = new RegExp('<' + tagName + '\\b[^>]*>([\\s\\S]*?)</' + tagName + '>', 'i')
  var m = xml.match(re)
  return m ? m[1].trim() : null
}

function escapeXml (s) {
  return String(s)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&apos;')
}

function buildFault (code, message) {
  return '<?xml version="1.0" encoding="UTF-8"?>' +
    '<Fault>' +
      '<Code>' + escapeXml(code) + '</Code>' +
      '<Message>' + escapeXml(message) + '</Message>' +
    '</Fault>'
}

```

Sample cURLs:

```auto
# Test the 404 path
curl -X POST "https://api.integrator.io/v1/apis/<your-api-id>/request" \
  -H "Authorization: Bearer <your-api-token>" \
  -H "Content-Type: application/xml" \
  --data '<Order><OrderId>999</OrderId></Order>'

# Test the 400 path (no OrderId)
curl -X POST "https://api.integrator.io/v1/apis/<your-api-id>/request" \
  -H "Authorization: Bearer <your-api-token>" \
  -H "Content-Type: application/xml" \
  --data '<Order><Customer>Acme</Customer></Order>'

# Send from a file instead of inline
curl -X POST "https://api.integrator.io/v1/apis/<your-api-id>/request" \
  -H "Authorization: Bearer <your-api-token>" \
  -H "Content-Type: application/xml" \
  --data-binary @order.xml

# See response headers (verify Content-Type: application/xml comes back)
curl -i -X POST "https://api.integrator.io/v1/apis/<your-api-id>/request" \
  -H "Authorization: Bearer <your-api-token>" \
  -H "Content-Type: application/xml" \
  --data '<Order><OrderId>123</OrderId></Order>'

```

Related articles:

- [Invoke a JavaScript API virtual export — Celigo Help Center](https://docs.celigo.com/hc/en-us/articles/360048159772-Invoke-a-JavaScript-API-virtual-export)
- [Invoke a JavaScript API virtual export with paging](https://docs.celigo.com/hc/en-us/articles/27633295437723-Invoke-a-JavaScript-API-virtual-export-with-paging)
- [integrator.io API and JavaScript runtime objects](https://docs.celigo.com/hc/en-us/articles/20239758683035-integrator-io-API-and-JavaScript-runtime-objects)
- [My API runVirtual error — Export type (Connective thread)](https://connective.celigo.com/t/my-api-runvirtual-error-export-type/1173)

---

<div class="post-metadata">

**Author:** ![James\_Mitchell](https://avatars.discourse-cdn.com/v4/letter/j/3be4f8/32.png) [@James\_Mitchell](https://connective.celigo.com/u/James_Mitchell)\
**Post date:** [April 30, 2026, 6:38pm UTC](https://connective.celigo.com/t/design-advice-xml-api-flow/6231/3 "2026-04-30T18:38:33Z")

</div>

> [@tylerlamparter](#):
>
> [integrator.io](http://integrator.io) API and JavaScript runtime objects

WOW 🤩

This is a fantastic starting point, thank you so much.

I really appreciate your effort on this.
