How to Export Data from Sage X3: Methods, API Limits & Portability
Complete technical guide to exporting data from Sage X3 using Import/Export templates, REST API, GraphQL, direct SQL, SVG extract, and what you can't get out.
Planning a migration?
Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.
Schedule a free call- 1,500+ migrations completed
- Zero downtime guaranteed
- Transparent, fixed pricing
- Project success responsibility
- Post-migration support included
TL;DR: Sage X3 has no single "Export All" button. Your best extraction path depends on deployment model and data volume: use the built-in Import/Export Template system (GEXPOBJ) for structured, repeatable bulk exports; use the REST Web API or GraphQL API for programmatic extraction and incremental sync; or query the underlying SQL Server/Oracle database directly for the fastest and most complete export on on-premise deployments. The biggest constraints: REST API throughput is governed by connection pool limits (default 4 channels in Syracuse) rather than published rate quotas, attachments require separate extraction from the file system and BLOB/CLOB tables, and workflow configurations and custom screen layouts cannot be exported through any standard method. Engineering resources are required for any complete data export.
Last verified: July 2025, against Sage X3 V12 (2026 R1) documentation. API behaviors reference both cloud (Sage X3 Online) and on-premise deployments.
Sage X3 (also known as Sage Enterprise Management) is a mid-market ERP covering financials, distribution, manufacturing, and supply chain. Its data model is organized around business objects — Products, Customers, Suppliers, Sales Orders, Purchase Orders, Invoices, Journal Entries, Inventory, Fixed Assets — each backed by one or more database tables in either SQL Server or Oracle.
Getting data out of X3 is not a single operation. It is a decision tree based on what you need, how much you need, and whether you are running on-premise, in a private cloud, or on Sage X3 Online. Because Sage X3 deployments are heavily customized with site-specific rules, multi-company/multi-folder structures (CPY and folder-level data separation), and custom Z-fields, extracting clean data requires understanding the Syracuse framework architecture of your specific instance.
This guide maps every extraction path, the real technical constraints of each method, and what data you will inevitably need to handle separately or lose during a standard export.
What Data Can You Export from Sage X3?
Sage X3 relies on a large underlying relational database (typically Microsoft SQL Server or Oracle). While the data exists, native UI and API capabilities filter what you can extract without custom engineering. There is nothing provided out-the-box to export all data. Every export requires deliberate configuration — selecting objects, defining templates, and validating output.
Here is the export availability for core Sage X3 objects based on the standard ERP data model.
| Object | UI/Template Export | API Export (REST/GraphQL) | Direct DB | Format | Known Limitations |
|---|---|---|---|---|---|
| Customers (BPC) | Yes | Yes | Yes | CSV, JSON, XML | Multi-address structures require header+line template design. Custom Z-fields must be manually added to export templates. |
| Suppliers (BPS) | Yes | Yes | Yes | CSV, JSON, XML | Bank details stored in separate tables; need explicit template groups. |
| Products / Items (ITM) | Yes | Yes | Yes | CSV, JSON, XML | Sales, purchase, and facility-level data split across ITMMASTER, ITMSALES, ITMFACILIT. UOM conversions require joining multiple tables. |
| Product-Sites (ITF) | Yes | Yes | Yes | CSV, JSON, XML | Often missed in migrations; site-level valuation, locations, and costing do not live on the product master alone. |
| Sales Orders (SOH) | Yes | Yes | Yes | CSV, JSON, XML | Header and line items export as separate record blocks. Tax calculation history is difficult to reconstruct outside X3. |
| Purchase Orders (POH) | Yes | Yes | Yes | CSV, JSON, XML | Approval workflow state may not export cleanly. |
| Sales Invoices (SIH) | Yes | Yes (Partial via GraphQL) | Yes | CSV, JSON, XML | PDF attachments require separate extraction. Header, footer, and line texts need template handling through GIMP fields. |
| Purchase Invoices (PIH) | Yes | Yes (Partial via GraphQL) | Yes | CSV, JSON, XML | Matching references (PO to Receipt to Invoice) rely on internal sequence IDs that lose context in flat exports. |
| Journal Entries (GACCENTRYD) | Yes | Yes | Yes | CSV, JSON, XML | Massive volume. UI exports will time out. Must use batch templates or SQL. |
| Chart of Accounts (GACCOUNT) | Yes | Yes | Yes | CSV, JSON, XML | Multi-ledger setups require specifying the exact ledger type. |
| Inventory / Stock | Yes | Yes (Partial via GraphQL) | Yes | CSV, JSON, XML | Multi-site, multi-lot structures require careful joins across STOCK and STOJOU. |
| Bill of Materials (BOM) | Yes | Yes (Partial via GraphQL) | Yes | CSV, JSON, XML | Nested BOM levels need recursive extraction. |
| Fixed Assets | Yes | Yes (Partial via GraphQL) | Yes | CSV, JSON, XML | Depreciation schedules stored across multiple tables. |
| Payments | Partial | Yes (Partial via GraphQL) | Yes | CSV, JSON | Payment export often uses custom utilities. Approval metadata only exists where the record was approved. |
| Attachments (AOBJTXT / ABLOB / ACLOB) | No | Partial | Yes | Binary/Files | Not included in standard data exports. Must extract attachment links and underlying volume/blob/clob store separately. |
| Audit Trail | Yes (grid) | Partial | Yes | CSV | Limited to visible log entries in UI; full history via audit tables in DB. |
| Workflow Configurations | No | No | Partial (unsupported) | — | No supported export method. |
| Crystal Reports | No | No | No | — | Proprietary .rpt files; cannot be converted. |
| User Roles / Permissions | No | No | Yes (DB) | DAT | Only via SVG full extraction or direct DB access. |
Field coverage gap between API facets: The REST $query facet returns a subset of fields compared to the $details facet. The $query facet is designed for list views and typically omits line-item details, extended descriptions, and custom fields. Always verify field coverage by comparing $query and $details responses for the same record. Sage X3 UI exports also natively drop internal record IDs (UPDTICK, CREUSR) and audit trail data unless you explicitly add them to the Import/Export template.
API and Feature Availability by X3 Version
Not all extraction methods are available across all X3 versions. This matrix covers the major deployment versions still in use:
| Capability | V6.5 / V7 | V11 (2017+) | V12 (2019+) | V12 2021 R2+ | V12 2026 R1 |
|---|---|---|---|---|---|
Import/Export Templates (GEXPOBJ) |
Yes | Yes | Yes | Yes | Yes |
| SOAP Web Services | Yes | Yes | Yes | Yes | Yes |
| REST Web API (SData 2.0) | No | Read-only (all modules) | Read-only + write (migrated modules) | Read-only + write (migrated modules) | Read-only + write (migrated modules) |
| GraphQL API | No | No | No | Yes (initial coverage) | Expanded coverage |
| Data Delivery API (Cloud) | No | No | Partial | Yes | Yes |
| SVG Data Extract | Yes | Yes | Yes | Yes | Yes |
GDPR Export Functions (GDPRLST, GDPREXP) |
No | Partial | Yes | Yes | Yes |
| Attachment Access Code restrictions | No | No | No | No | Yes (new in 2026 R1) |
Check your exact patch level. GraphQL coverage expands with each release — use schema introspection (__schema { types { name } }) on your endpoint to confirm available nodes.
Export Methods: Every Way to Get Data Out of Sage X3
Sage X3 offers six distinct extraction paths. The right choice depends on your volume, technical capacity, and deployment model (on-premise vs. Sage X3 Online).
| Method | Data Coverage | Volume Limit | Speed | Complexity | Best For |
|---|---|---|---|---|---|
| UI CSV Export | Single grid/screen | Visible rows only (~10–20K max) | Fast (small sets) | Low | Ad-hoc spot checks |
Import/Export Templates (GEXPOBJ) |
Any object with a template | No hard limit (batch) | Medium | Medium | Repeatable, structured bulk exports |
| REST Web API (SData 2.0) | All modules (read-only for classic) | Pagination-dependent | Medium | High | Integration, incremental sync |
| GraphQL API | V12 2021 R2+ modules with nodes | Pagination-dependent | Medium | High | Selective field extraction |
| SVG Data Extract | All tables in a folder | Full database | Slow for large DBs | Medium | Full backup, cross-DB migration |
| Direct Database Access | Everything | No limit | Fastest | High | Bulk migration, reporting |
Decision criteria: UI CSV Export and Import/Export Templates require zero engineering — an X3 admin or power user can run them. REST, GraphQL, and direct DB access require developer resources. Two rules change the plan immediately: file-based integration is not available in Sage X3 Online, and direct SQL is only supported on-premise.
Integration Platform Connectors
Teams using integration platforms should note that pre-built connectors exist for Sage X3 on Boomi, MuleSoft, and Celigo. These connectors typically wrap the REST or SOAP APIs and provide visual mapping tools, error handling, and scheduling. They do not bypass the underlying API constraints (connection pools, field coverage gaps), but they reduce the engineering effort for recurring extractions. Evaluate whether a connector covers your specific objects before building custom API scripts.
Native UI Export (CSV)
The CSV file export is intended to export grid data to a file. To export the content of a grid to a CSV file, use the drop-down menu next to the grid and pick the option "CSV export." Once the export dialog shows up, click on export to create the CSV file.
Step-by-step from any list screen:
- Navigate to the desired function (e.g., All > Sales > Orders > Orders for sales orders).
- Apply any filters or date ranges in the inquiry/list view.
- Click the drop-down arrow next to the grid header.
- Select CSV Export.
- In the export dialog, click Export — the file downloads to your browser.
What this gets you: The visible columns in the current grid view, in CSV format with your system's locale settings (date format, decimal separator).
What this misses:
- Only exports rows currently loaded in the grid — not the full dataset behind the query. The Syracuse web server will time out or hit memory errors on exports above 10,000–20,000 records.
- Line-item details (e.g., order lines, invoice lines) are not included when exporting from a header-level list.
- Custom fields may not appear unless the grid view has been explicitly configured to show them.
- Attachments and documents are completely excluded.
- Relationships between objects (e.g., which invoice relates to which PO) are not preserved as foreign keys.
UI CSV export is useful for quick ad-hoc pulls of a few hundred records. Do not use it for migration or backup — it is not repeatable, not auditable, and silently truncates large datasets.
How to Bulk Export Data Using Import/Export Templates
X3 provides a comprehensive infrastructure to support imports and exports. Imports and exports are governed by templates, which define the interface between an object and the outside world. The data fields and tables are described, along with information about the structure of the external data.
This is the most structured native export method and the primary extraction tool for teams without backend SQL access. Templates map X3 object fields to file columns and support CSV, XML, and DAT formats.
Step-by-step:
- Navigate to Setup > Usage > Imports/Exports > Import/Export Template (function
GESAOE). - Select an existing template (e.g.,
ITMfor Products,SOHfor Sales Orders,BPCfor Customers) or create a custom one. - On the Fields tab, verify which fields are included — add or remove fields as needed. Make sure child tables, text fields, and any finance or dimension data are included in the correct groups.
- Set the file type (CSV, XML, or DAT) and configure field/record separators.
- Navigate to Usage > Imports/Exports > Exports (function
GEXPOBJ). - Select your template and specify the output file location (server for batch processing into a volume directory, or client for immediate download).
- Under Criteria, set your filters (e.g., date ranges, specific company/site codes) to limit the data volume.
- Click OK to execute. For large datasets, allow the batch server time to process.
Data is exported via templates which specify the fields exposed for exporting, as well as the data file type, the field and record separators, and the record types used in the destination file. Templates are also used to define fields that can be used as criteria to filter exported data.
Key behaviors and gotchas:
- If you wish to export the same records more than once, you will need to uncheck the Chrono management option. For many tables, X3 tracks which records have been exported, and this option can prevent re-exporting records that have not changed. Chrono management is driven by the
EXPNUMfield on transaction headers and certain master tables. To determine whether a specific table supports chrono management, check whether theEXPNUMcolumn exists in the table structure via Development > Dictionary > Tables. To reset chrono tracking for a re-export, setEXPNUMto 0 on the target records via SQL or uncheck the chrono option in the template. - When an object spans multiple tables (e.g., a sales order with header and lines), the export produces multiple record blocks per instance — one header block followed by N line blocks. Header data repeats for every line item in CSV outputs.
- File-based importing and exporting is well suited to processing large amounts of data, and the process can be automated through user-defined time scheduling of batch jobs.
- The export handles millions of rows but can take hours for massive tables like Journal Entries. Schedule batch runs overnight to avoid locking active tables.
- Attachments are entirely ignored by template exports. Audit history (who changed what and when) is not included unless you explicitly build a template targeting the audit tables.
- If a field appears in the UI but not in your export file, start with the template, not the database. The X3 export engine picks the first available dictionary link when several links exist, which can produce the wrong join if you design the groups carelessly.
Effort estimate: An X3 administrator with template knowledge can configure and run these without developer involvement. Budget 1–2 days for template setup and validation per major object type (products, customers, orders, invoices, journal entries each count as separate object types).
API-Based Export: Endpoints, Pagination, and Rate Limits
Sage X3 exposes multiple API surfaces for programmatic data extraction. Your choice depends on your X3 version, deployment model, and whether you need read or write access.
REST Web API (SData 2.0)
The Web API can be used to read data from all modules, as Sage X3 is already providing read-only representations on all resources. The SOAP interface has been available since V6 and remains the primary mechanism for write operations on classic modules — the REST/SData 2.0 Web API provides read-only access to classic module data.
Authentication:
- The online deployment imposes OAuth2 authentication, while the on-premise deployment also supports basic and client certificate authentication.
- On-premise: Basic Auth (username/password in
Authorizationheader), Client Certificate, or OAuth 2.0 - Cloud (Sage X3 Online): OAuth 2.0 only. The grant type is Client Credentials. You configure a Connected App in Syracuse administration, which provides a Client ID and Client Secret. The token endpoint follows the pattern
https://{syracuse-host}/auth/oauth/token. Include the token as a Bearer token in theAuthorizationheader. Tokens expire (typically 3600 seconds) — your extraction script must handle refresh. - The API user consumes a Web Services Badge license.
Endpoint structure:
An example of a request: http://x3server:8124/api1/x3/erp/SEED/SORDER?representation=SORDER.$query&count=10
The URL pattern is:
http://{server}:{port}/api1/x3/erp/{FOLDER}/{REPRESENTATION}?representation={REP}.{$facet}&count={N}
The following facets are available for each Representation: 1) Detail 2) Edit 3) Query 4) Lookup 5) Summary.
$query— Returns a paginated list of records with summary fields. Use for listing and iteration.$details— Returns the full record with all fields, including line items. Use for individual record extraction.$lookup— Minimal fields for dropdown/search scenarios.
Pagination:
The REST API uses offset-based pagination via count and startIndex query parameters:
GET /api1/x3/erp/SEED/SORDER?representation=SORDER.$query&count=50&startIndex=51
The default page size is 20 records. You can request more via count=N, but the server may cap the value. In practice, count=100 is a safe upper bound — requesting larger pages can cause timeouts on complex objects with many line items. The safest way to paginate is to follow the returned $links.$next.$url rather than constructing next-page URLs yourself.
Rate limits and connection pools:
Sage does not publish explicit "requests per minute" rate limits for the X3 REST API. Respect rate limits, even if they are undocumented. Observability will reveal sustainable request-per-second levels.
Instead of traditional rate limits, Sage X3 uses connection pools configured in the Syracuse administration panel (Administration > Servers > Connection pools). Each pool has a maximum number of channels — the default is typically 4 channels per pool. Each API request occupies one channel for the duration of the request. If all channels are busy, subsequent requests are queued. If the queue timeout (configurable, typically 30–60 seconds) is exceeded, the API returns an HTTP 503 (Service Unavailable) with an X3-specific error message referencing pool exhaustion (e.g., "No available connection in pool"). Cloud deployments are subject to additional infrastructure throttling, which typically surfaces as HTTP 429 responses with a Retry-After header.
To increase throughput on on-premise deployments, you can add channels to the pool or create additional pools — but each channel consumes server memory and a database connection, so this must be coordinated with your DBA.
Extraction script:
To safely extract data via the REST API without exhausting the connection pool, your script needs concurrency controls, backoff logic, and fault tolerance for partial failures.
import requests
import time
import json
import os
BASE_URL = "https://x3server:8124/api1/x3/erp/MYCO"
REP = "BPCUSTOMER"
PAGE_SIZE = 50
AUTH = ("ws_user", "password")
OUTPUT_FILE = "customers_export.json"
CHECKPOINT_FILE = "export_checkpoint.json"
def load_checkpoint():
"""Resume from last successful page if script was interrupted."""
if os.path.exists(CHECKPOINT_FILE):
with open(CHECKPOINT_FILE) as f:
return json.load(f)
return {"last_url": None, "exported_keys": []}
def save_checkpoint(url, exported_keys):
with open(CHECKPOINT_FILE, "w") as f:
json.dump({"last_url": url, "exported_keys": exported_keys}, f)
def fetch_with_retry(url, max_retries=3):
"""Fetch a URL with retry logic for 429/503 errors and network failures."""
for attempt in range(max_retries):
try:
resp = requests.get(url, auth=AUTH, timeout=60)
if resp.status_code in (429, 503):
retry_after = int(resp.headers.get("Retry-After", 10 * (attempt + 1)))
print(f"Rate limited ({resp.status_code}). Waiting {retry_after}s...")
time.sleep(retry_after)
continue
resp.raise_for_status()
return resp.json()
except requests.exceptions.RequestException as e:
print(f"Network error on attempt {attempt + 1}: {e}")
time.sleep(5 * (attempt + 1))
raise RuntimeError(f"Failed to fetch {url} after {max_retries} retries")
def export_all_records():
checkpoint = load_checkpoint()
all_records = []
exported_keys = set(checkpoint.get("exported_keys", []))
url = checkpoint.get("last_url") or \
f"{BASE_URL}/{REP}?representation={REP}.$query&count={PAGE_SIZE}"
while url:
data = fetch_with_retry(url)
resources = data.get("$resources", [])
if not resources:
break
for record in resources:
record_key = record.get("$key")
if record_key in exported_keys:
continue # Skip already-exported records on resume
detail_url = f"{BASE_URL}/{REP}('{record_key}')" \
f"?representation={REP}.$details"
detail_data = fetch_with_retry(detail_url)
all_records.append(detail_data)
exported_keys.add(record_key)
time.sleep(0.2) # Throttle to ~5 req/sec per channel
# Follow next link from response — do not construct manually
next_link = data.get("$links", {}).get("$next", {}).get("$url")
save_checkpoint(next_link, list(exported_keys))
url = next_link
with open(OUTPUT_FILE, "w") as f:
json.dump(all_records, f, indent=2)
print(f"Exported {len(all_records)} records to {OUTPUT_FILE}")
return all_recordsImportant caveats about this script: This is a functional skeleton, not production-grade migration code. The $links.$next.$url path structure may vary across X3 versions and Syracuse configurations. For production use, add: logging, output streaming (write records incrementally rather than holding all in memory), deduplication validation post-export, and integration tests against your specific X3 instance.
Throughput math: At a conservative 5 requests/second with per-record detail fetches, you can extract approximately 1,000–1,500 full records per hour for complex objects like Sales Orders (which require a list query + detail fetch per record). Simpler objects with flat structures can reach 3,000–5,000 records/hour using query-only extraction. With a 4-channel pool and multi-threaded requests, you can increase throughput proportionally — but you risk locking the pool and blocking live integrations or UI users sharing the same pool. This method is not designed for bulk historical extraction of 100K+ records.
Incremental / Delta Extraction Using UPDTICK
For teams building ongoing sync rather than one-time exports, the key challenge is identifying which records have changed since the last extraction.
Sage X3 maintains an UPDTICK field on most transaction and master tables. This is an integer that increments each time a record is modified. It functions as an optimistic concurrency token and can be used as a change marker.
How to use it for incremental sync:
- On your first extraction, record the maximum
UPDTICKvalue across the table. - On subsequent extractions, query for records where
UPDTICK > {last_recorded_value}. - Via the REST API, you can filter using:
?where=UPDTICK gt '{value}' - Via direct SQL:
SELECT * FROM SORDER WHERE UPDTICK > @lastTick
Limitations:
UPDTICKidentifies modified records but does not capture deleted records. If records are hard-deleted from X3, you will not detect the deletion viaUPDTICKalone. You need a separate reconciliation step comparing current record keys against your last full extract.- Not all tables have
UPDTICK. Verify its existence in the data dictionary for each table you plan to sync. - The
UPDTICKvalue is not a timestamp — it is an ordinal. You cannot convert it to a date without correlating it with audit log entries. - The REST API's
whereclause support varies by representation. Test your filter syntax against your specific endpoint before building automation around it.
GraphQL API
Starting Sage X3 2021 R2 (V12), a new integration pathway has been introduced: GraphQL. GraphQL has gained massive popularity for its lightweight query and response profiles, and Sage X3 has been embracing this new technology for integration with third-party applications since mid-2021.
Authentication uses JWT. You need to create a Connected App in your Sage X3 environment that provides the Client ID, Client Secret, Issuer, and Audience values required for authentication.
GraphQL lets you specify exactly which fields to return, reducing payload size. Example query for customers:
{
sage {
x3BusinessPartners {
customer(orderBy: "{ code: 1 }", first: 50) {
edges {
node {
code
companyName
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}To paginate, use cursor-based navigation with the after argument:
{
sage {
x3BusinessPartners {
customer(orderBy: "{ code: 1 }", first: 50, after: "CURSOR_VALUE") {
edges {
node {
code
companyName
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}
}Sage is adding new queries and integrations (also called mutations in GraphQL lingo) with every release, so it is worth being on the latest version. GraphQL coverage is growing but does not yet cover all X3 modules. Use schema introspection to see what is available in your version:
{
__schema {
types {
name
fields { name }
}
}
}Queries are limited to 20 results on the demo endpoint. Production endpoints support larger page sizes via the first argument.
SOAP Web Services
SOAP is the mature, full-featured option for classic modules. REST (SData 2.0) is the modern successor, but only supports write operations on service-oriented (migrated) modules.
For modules that have not been migrated to the new service-oriented architecture, SOAP (via the CAdxWebServiceXmlCC service) remains the only way to perform write operations. For export (read) purposes, the REST API generally provides equivalent or better access. Many legacy integrations still rely on SOAP, and it can be useful for scheduled template-based exchanges.
Data Delivery API (Cloud Only)
The Data Delivery API allows you to download files generated by an X3 export task. The export task needs to be created by the administrator of the X3 cluster for third-party applications.
This is the designated cloud export path: an admin sets up a scheduled export task within X3, which generates files to a virtual folder. External applications then poll the Data Delivery endpoint to download those files. This is the right approach for recurring, automated extractions on Sage X3 Online where direct file system and database access are unavailable.
How to Export Data Directly from the Sage X3 Database
For on-premise deployments, direct SQL access to the underlying database is the fastest and most complete extraction method.
Sage X3 versions 6.5, 7, 8, 9, 11 and 12 can be deployed on an SQL Server or an Oracle Database. There is no limit to the size of the database. Most customers are below 100 GB, however some implementations are using several terabytes.
Sage X3 table naming uses abbreviated, non-intuitive conventions. Without the data dictionary, mapping SORDERP.NETPRI_0 to "net price" is guesswork. Always cross-reference with the X3 data dictionary (Development > Dictionary > Tables) to map field names.
Key tables:
| ERP Object | Primary Table(s) | Notes |
|---|---|---|
| Customers | BPCUSTOMER |
Business Partner - Customer |
| Suppliers | BPSUPPLIER |
Business Partner - Supplier |
| Products | ITMMASTER, ITMSALES, ITMFACILIT |
Master, sales, and facility-level data split across tables |
| Sales Order Headers | SORDER |
Header table |
| Sales Order Lines | SORDERQ, SORDERP |
Quantity and price line tables |
| Purchase Order Headers | PORDER |
Header table |
| Sales Invoice Headers | SINVOICE |
Header table |
| Journal Entries | GACCENTRYD |
Detail journal entry lines |
| Stock / Inventory | STOCK, STOJOU |
Current stock and stock journal |
| Fixed Assets | FXDASSET |
Asset master |
Sample SQL: Joining Sales Order Header and Lines
This query extracts sales orders with line-level detail, filtered by site code. Adapt the column list to your specific needs using the X3 data dictionary.
-- SQL Server syntax. For Oracle, replace TOP with ROWNUM or FETCH FIRST.
SELECT
h.SOHNUM_0 AS order_number,
h.ORDDAT_0 AS order_date,
h.BPCORD_0 AS customer_code,
h.CUR_0 AS currency,
h.FCY_0 AS site_code,
q.SOPLIN_0 AS line_number,
q.ITMREF_0 AS item_code,
q.QTY_0 AS quantity,
q.SAU_0 AS unit_of_measure,
p.NETPRI_0 AS net_unit_price,
p.NETPRIATI_0 AS net_price_incl_tax,
p.DISCRGVAL1_0 AS discount_pct_1,
h.UPDTICK AS change_token
FROM SORDER h
INNER JOIN SORDERQ q
ON h.SOHNUM_0 = q.SOHNUM_0
INNER JOIN SORDERP p
ON h.SOHNUM_0 = p.SOHNUM_0
AND q.SOPLIN_0 = p.SOPLIN_0
WHERE h.FCY_0 = 'NA010' -- Filter by site/facility
AND h.ORDDAT_0 >= '20240101' -- Filter by date (YYYYMMDD internal format)
ORDER BY h.SOHNUM_0, q.SOPLIN_0;Export the results using bcp (SQL Server) or SQL*Plus spool (Oracle):
# SQL Server: export to CSV via bcp
bcp "SELECT ... FROM SORDER h INNER JOIN ..." queryout orders.csv -c -t"," -S servername -d x3database -U user -P passDirect database access bypasses X3's business logic layer. It gives you 100% of your data, but it requires deep knowledge of the X3 schema — how multi-site data is partitioned using the FCY field, how dimension arrays are numbered (DIM_0 through DIM_9), and how parent-child tables relate. Multi-company deployments using separate folders will have entirely separate database schemas. This is the only method that reliably handles datasets above 500,000 records without timeout issues.
If you are building a relational migration, you must manually include ROWID or primary key fields to maintain relationships in your target system. Multi-site data requires filtering or partitioning by the FCY (facility/site) field. Multi-company data requires determining whether companies share a folder (filtered by CPY) or occupy separate folders (separate databases or schemas).
Does Sage X3 Have a Full Backup Export? (SVG Data Extract)
Yes. This function makes it possible to extract the data in one or more tables in an X3 folder, by creating files containing the table description and the stored data, in a sub-directory of the folder (SVG by default).
Access it via Development > Utilities > Extraction/Integration > Data Extract.
For each table, four to six files are created: a .dat file containing the data as fixed-length records, a .srf file with the structure description in ASCII format, a .fde file with the compiled structure, and a .seq file with the next sequence number.
The SVG extract is useful for creating a portable copy of your entire X3 folder that can be restored into another X3 instance — even across database platforms (SQL Server to Oracle or vice versa). The neutral flat file format enables migration between SQL Server and Oracle, though this format is not adapted to very large volumes.
This function should not be used as a habitual backup procedure since it does not have the guarantees of security or performance. A backup with standard database tools is strongly recommended. If launched for several database tables, it can lead to a database image that is not globally coherent if updates take place during the export.
The SVG extract format is X3-proprietary — it is designed for X3-to-X3 transfers, not for loading into another platform. For genuine backups, use native database tools (SQL Server .bak or Oracle RMAN).
Exporting Attachments, Files, and Media from Sage X3
Sage X3 handles attachments in a specific way. They are rarely stored directly in the database as BLOBs. Instead, the system uses a split architecture:
- The
AOBJTXTtable stores attachment links and metadata (which record the attachment belongs to, the file pointer, the attachment type code). ABLOBstores database-backed binary content (images, PDFs).ACLOBstores database-backed text content.- Physical files can also reside on the application server's file system within designated volume directories (e.g., the
DOCdirectory under the folder path), organized by object type.
The key constraints:
- Standard exports do not include attachments. Neither Import/Export Templates nor the REST API automatically bundle attachments with record exports.
- The REST API can retrieve document metadata, and the collaboration API can enumerate documents by volume, but downloading actual binary files in bulk via API is slow and often unsupported depending on the object.
- Since 2026 R1 / V12.0.39, attachment access codes can restrict download permissions for specific users, so your export account's access codes must cover all attachment types you need.
The practical workflow:
- Export your business records through templates or API.
- Query the attachment metadata tables (
AOBJTXT) to get file paths and associated record keys:SELECT OBESSION_0, OBESSION_1, OBESSION_2, VOLUME_0, ESSION_0, ESSION_1 FROM AOBJTXT WHERE OBESSION_0 = 'SOH' -- Object type (e.g., Sales Orders) - Copy the referenced volume files from the server file system or dump
ABLOB/ACLOBcontent from the database. - Preserve the join between each business record key and its associated files so attachments can be re-associated in your target system.
On cloud deployments, server file system access requires coordination with Sage support or your hosting partner, so plan this extraction phase separately and early.
What Data Cannot Be Exported from Sage X3?
Be explicit about what you will lose or need to rebuild manually:
| Data Type | Exportable? | Workaround |
|---|---|---|
| Workflow / Approval Routing | No | Trapped in the X3 code dictionary and workflow engine. Must be manually documented and recreated in the target system. |
| Crystal Reports definitions | No | Proprietary .rpt files. Source files can be copied from the server but cannot be converted to another format. Must be rebuilt in the target reporting tool. |
| Custom screen layouts | No | Stored in the X3 dictionary; must be manually recreated. |
| User Passwords / Syracuse profiles | No | User records exportable, but auth hashes, role assignments, and dashboard layouts cannot be ported. |
| Custom Views / Saved Inquiries | No (via API) | Native to the Syracuse web presentation layer. Can sometimes be extracted from dictionary tables via direct DB but not in a portable format. |
| Integration Configurations | No | Workflow triggers, outbound REST configs must be documented manually. |
| Deleted / Purged records | No | Once hard-deleted from the database, the data is gone. No "recycle bin" API endpoint. |
| Dashboard / BI configurations | No | Analytics layouts are user-specific and not exportable. |
If you are asked whether Sage X3 lets you export everything, the honest answer is: not through one supported self-serve method. Core ERP transactional and master data is accessible through templates, APIs, or direct SQL. Attachments, admin metadata, permissions, and historical audit evidence each need separate extraction plans with dedicated engineering effort.
Data Format, Encoding, and Cleanup After Export
Sage X3 is a global ERP, and its exported data has characteristics that can cause downstream failures if not handled carefully.
Encoding:
Export templates allow you to choose ASCII, UTF-8, or UCS-2. Always force UTF-8. Legacy templates sometimes default to ANSI/Windows-1252, which will corrupt special characters in customer names, addresses, or item descriptions containing diacritics or CJK characters.
Date formats:
Sage X3 stores dates internally in YYYYMMDD format (without dashes) in the database, but API and template exports often format them based on the user's locale (e.g., DD/MM/YYYY for European users, MM/DD/YYYY for US). Be mindful of language and date formatting in multi-country deployments. Multi-country X3 deployments may produce mixed date formats and decimal separators across sites. Always normalize dates to ISO 8601 (YYYY-MM-DD) post-export.
Field separators:
Import/Export templates let you configure separators, but the default is often a semicolon (;) rather than a comma — this is the standard in European X3 deployments (where commas are decimal separators) and will break naive CSV parsers expecting comma delimiters.
Local menus (drop-downs):
Sage X3 stores drop-down values as integers internally (e.g., 1 for Pending, 2 for Approved). The text label lives in the APLSTD table, keyed by language, menu number, and option number. If you export raw data, you will get the integer, not the human-readable text. You must either join the local menu table or use an export template that translates the values via the Transcribe option.
Multi-value fields:
X3 uses dimension arrays for certain fields (e.g., descriptions in multiple languages, multi-site pricing, analytical dimensions). These export as multiple numbered columns (e.g., DES_0, DES_1, DES_2 for description in language 0, 1, 2; or CCE_0 through CCE_9 for analytical dimensions).
Internal codes vs. descriptions:
X3 exports produce internal codes by default (e.g., BRR for a product category), not human-readable descriptions. Use the Transcribe Import/Export feature to map codes to external values if needed for human review.
User authorization filtering:
Exports are filtered by user authorizations. A service account with restricted site visibility, company access, or functional profile will produce a smaller dataset without any warning or error. Always verify your export account has full access (* authorization) to the data you need. Compare your export row counts against the counts shown in X3's statistics functions.
Post-export validation checklist:
- ☐ Row counts match source system totals per object (compare against X3 inquiry totals or
SELECT COUNT(*)) - ☐ Date formats are consistent across all files (no locale mixing between sites)
- ☐ Decimal precision preserved (especially currency amounts — X3 supports up to 8 decimal places)
- ☐ Foreign key references resolve (e.g., every order line references a valid order header)
- ☐ Multi-language description fields captured for all required languages
- ☐ Closed/archived records included if needed for historical migration
- ☐ Chart of accounts segments and dimensions export correctly across all dimension types
- ☐ Tax codes and rates are present with effective dates
- ☐ Spot-check for permission-based omissions: run a count query as a full-access user and compare against export totals from the actual service account
- ☐ Local menu integers are translated to text labels where the target system requires them
Export for Migration vs. Backup vs. Compliance
Your extraction strategy must match your use case. These three scenarios require fundamentally different approaches.
Migration requires relationship-aware extraction. You need customers before sales orders, products before BOM structures, and chart of accounts before journal entries. Header and line items must stay linked. The Import/Export Template system preserves header-line relationships within a single object, but cross-object references (e.g., linking an invoice back to the original sales order via SOHNUM) require explicit mapping tables. ID mapping between X3 internal keys and target system keys must be planned before extraction begins. Direct SQL or complex Import/Export templates are required for enterprise migrations covering more than a handful of objects.
Backup requires a full-fidelity snapshot. The SVG extract or a database-level backup (SQL Server .bak or Oracle RMAN) is the right tool. SVG gives you portability across database platforms; native database backup gives you consistency guarantees (point-in-time recovery, transactional integrity). API exports are not valid backups for an ERP — they lack the transactional consistency and completeness guarantees.
Compliance (GDPR/DSAR) requires targeted extraction. The standard features of Sage X3 provide tools to help comply with GDPR. A new GDPR visual process has been added to the Data administrator home page. With these tools, you can identify a Data Protection Officer, export all the fields associated to individuals. Two dedicated exports are provided to help you extract personal data in CSV format, which can be exported to an Excel spreadsheet.
The specific functions are:
GDPRLST— Lists all personal data fields tagged in the GDPR data type dictionaryGDPREXP— Exports personal data for a specific individual across Customers, Contacts, Users, and Business Partners
These cover fields tagged as personal data in the GDPR data type dictionary. However, they do not cover operational data that may contain personal information embedded in free-text fields (order notes, comments, descriptions), attachments containing personal data, or audit logs showing user activity. A defensible GDPR Article 15 (access request) or Article 20 (data portability) response still requires scoping beyond what these functions provide, particularly for identifying personal data across custom Z-fields and free-text entries.
Vendor Lock-In and Data Portability Assessment
Sage X3 does not lock your data behind proprietary walls the way some cloud-only platforms do. The underlying SQL Server or Oracle database is fully accessible on on-premise deployments, and every table can be queried directly. The Import/Export Template system provides structured extraction for most business objects. The REST and GraphQL APIs give programmatic read access to all modules.
No contractual export restrictions. Sage does not contractually restrict data export in standard licensing terms. You own your data.
What creates friction is not access restrictions but structural complexity:
- No "Export Everything" button. Every object requires deliberate template configuration or API scripting. A full export project for a mid-size X3 deployment (50+ active objects, 100K+ records across 5–10 modules) typically requires 2–4 weeks of engineering work.
- Schema complexity. X3's table structure uses abbreviated, non-intuitive naming. Without the data dictionary, field mapping is guesswork. A single business object like a sales order spans 3+ tables (
SORDER,SORDERQ,SORDERP, plus text and analysis tables). - Cloud restrictions. Sage X3 Online users lose direct database and file system access — you are limited to REST, GraphQL, Data Delivery API, and Import/Export Templates. This removes the fastest and most complete extraction path.
- Business logic is locked in the application layer. Exporting the raw data is achievable; interpreting it outside of Sage X3 is the real challenge. How a unit of measure converts, how a price is calculated from multiple matrix tables (
PRICLIST,PPRICLIST), how approval routing works — these rules live in the 4GL application code, not in the data. The switching cost is less about data extraction and more about data transformation and reverse-engineering customized business rules.
Timeline and Resourcing for a Full Data Export
Extracting data for a full ERP replacement is a major project phase. The elapsed time is usually driven less by raw extraction speed than by template design, attachment handling, and validation loops.
| Dataset Size | Scoping | Template/API Setup | Extraction | Validation & Cleanup | Total |
|---|---|---|---|---|---|
| Small (<10K records, <5 objects) | 1–2 days | 2–3 days | 1 day | 1–2 days | 5–8 days |
| Medium (10K–100K records, 5–15 objects, single site) | 2–3 days | 3–5 days | 1–2 days | 3–5 days | 9–15 days |
| Large (100K+ records, 15+ objects, multi-site/multi-company) | 3–5 days | 5–10 days | 2–5 days | 5–10 days | 15–30 days |
These estimates assume an experienced team. First-time X3 migrations commonly exceed these ranges by 50–100% due to schema discovery, custom field mapping, and unexpected data quality issues.
Minimum team composition by method:
- Template-based export: 1 X3 administrator with template knowledge (no developer needed)
- API-based export: 1 developer familiar with REST/GraphQL + 1 X3 functional consultant for data mapping
- Direct DB export: 1 SQL developer/DBA + 1 X3 functional consultant for schema interpretation
- Full migration export: 1 project manager + 1 developer + 1 X3 functional consultant + 1 target system specialist
The validation phase consistently takes longer than teams expect. ERP data has deep interdependencies — a single mismatched currency code, fiscal period boundary, or site code can cascade through thousands of transactions. Budget at least 30% of total project time for validation and cleanup.
Your Next Steps
Exporting data from Sage X3 is an engineering task that requires deliberate method selection for each data type.
Method selection summary:
- < 10K records, ad-hoc: UI CSV export
- Structured bulk export, repeatable: Import/Export Templates (
GEXPOBJ) - Ongoing integration / incremental sync: REST API with
UPDTICK-based delta detection - Full historical extraction, on-premise: Direct SQL with schema mapping from the X3 data dictionary
- Cloud deployment, recurring: Import/Export Templates + Data Delivery API
- Attachments: Separate extraction phase via
AOBJTXTmetadata + file system or BLOB dump - Backup: Native database tools (SQL Server
.bak/ Oracle RMAN), not API or SVG
Before starting, complete four prerequisite steps: map your schema using the X3 data dictionary, verify your export account's authorization level covers all sites and companies, standardize your date and encoding settings across templates, and validate your local menu integer-to-text mappings before loading data into your target platform.
The first file that downloads successfully is not a migration-ready export. It is the beginning of a validation cycle.
Frequently Asked Questions
- Can I export all my data from Sage X3?
- Yes, but not with a single button click. Sage X3 provides no out-of-the-box option to export all data at once. You need a combination of Import/Export Templates (for structured business objects), API calls (for programmatic extraction), and direct database queries (for on-premise deployments). The SVG Data Extract function can dump all tables, but in a proprietary flat-file format designed for X3-to-X3 transfers, not for loading into another platform.
- Does Sage X3 export include attachments?
- No. Standard exports via Import/Export Templates and the REST API do not include document attachments. Attachments are stored separately — metadata in the AOBJTXT table, binary content in ABLOB, text content in ACLOB, and physical files on the server's volume directories. You must extract them separately by mapping attachment metadata to file paths, then copying the files via SFTP or direct server access.
- How long does it take to export data from Sage X3?
- For a small dataset under 10,000 records across a few objects, a knowledgeable X3 admin can complete the export in under a week using Import/Export Templates. For large datasets (100,000+ records across dozens of objects with multi-site and multi-currency complexity), expect 3–4 weeks including template configuration, extraction, and validation.
- What format does Sage X3 export data in?
- Sage X3 supports CSV, XML, and DAT (proprietary flat-file) formats via Import/Export Templates. The REST API returns JSON. The GraphQL API also returns JSON. The SVG Data Extract produces proprietary .dat files with associated .srf structure files. UI grid exports produce CSV with locale-specific formatting.
- Can I export Sage X3 data for GDPR compliance?
- Partially. Sage X3 provides two dedicated exports for extracting personal data (emails, phone numbers, personal details) in CSV format, based on the GDPR data type dictionary. These cover fields tagged as personal data across Customers, Contacts, Users, and Business Partners. However, they do not cover your full operational dataset — a defensible DSAR response still requires scoping, attachment handling, and review.


