The Syteline IDO system is self-describing. Every IDO, its properties, methods, tables, and relationships can be discovered through the same REST API. An agent can explore the system without prior knowledge of any specific IDO.
Base URL: $SYTELINE_BASE_URL
All examples assume $TOKEN is set (see 01_AUTHENTICATION.md).
-
Always set
recordcap=10(or similar small number) during discovery. Broad queries without a cap can return thousands of rows and overwhelm the response. Only userecordcap=0(all rows) when you have a narrow filter and need the complete set. -
Omit
properties(or useproperties=*) to get all properties during discovery. When exploring an unfamiliar IDO, seeing all columns helps you confirm you found the right one. Once you know what you need, narrow to specific properties for efficiency. -
You can always fall back to the core meta-IDOs. When you're stuck, these are the IDOs that describe the system itself:
| Meta-IDO | What it tells you |
|---|---|
IdoCollections |
All IDO names, AccessAs (core vs custom) |
IdoProperties |
Properties on any IDO — types, bound columns, expressions |
IdoMethods |
Methods on any IDO — SP or extension class |
IdoMethodParameters |
Method parameter names, types, sequence, direction |
IdoTables |
Database tables backing any IDO, join relationships |
SqlColumns |
Raw database columns, types, primary key flags |
SqlTableKeys |
Constraints on database tables |
- It's okay to try things. The agent user is scoped to read-only introspection. An exploratory LoadCollection or Invoke that fails will return a clear error message, not break anything. However, ask the user before executing methods that modify data (Insert, Update, Delete, or Invoke on methods that change state) — those should use the automation user if configured.
Finding the right IDO is the first and hardest challenge. There are several strategies depending on what you know.
If you know (or can guess) part of the IDO name:
curl -s "$SYTELINE_BASE_URL/load/IdoCollections?properties=CollectionName,AccessAs&filter=CollectionName%20LIKE%20N'%25ItemPrice%25'&recordcap=10" \
-H "Authorization: $TOKEN"AccessAs helps distinguish core vs custom IDOs:
AccessAs = 'BaseSyteLine'→ Core Syteline IDO (delivered by Infor)AccessAs = ''(empty) → Custom IDO (added by the implementation team, often prefixed with a company identifier likeCMP_)
If you're converting a SQL script that calls a stored procedure, search by method name (the IDO method name usually matches or closely resembles the SP name):
curl -s "$SYTELINE_BASE_URL/load/IdoMethods?properties=CollectionName,MethodName,MethodType&filter=MethodName%20LIKE%20N'%25ItemPriceChangeSp%25'&recordcap=10" \
-H "Authorization: $TOKEN"Note: The
StoredProcedureproperty does not exist onIdoMethodsin all environments — you'll get"Property StoredProcedure not found". Filter byMethodNameinstead; the method name is sufficient.
This directly tells you which IDO hosts the method and whether it's a stored procedure or extension class.
If you know the SQL table (e.g., from a DELETE FROM itemprice statement), find which IDO uses it:
curl -s "$SYTELINE_BASE_URL/load/IdoTables?properties=CollectionName,TableName,TableType,JoinType&filter=TableName%20%3D%20N'itemprice'&recordcap=10" \
-H "Authorization: $TOKEN"TableType values:
3= Primary Base Table (the IDO's main table)0= Secondary Table (joined to the primary)
You usually want the IDO where your table is the Primary Base Table (TableType=3).
If multiple IDOs share the same primary table, check AccessAs on IdoCollections to find the core one (or use the CMP_-prefixed extended version if it exists — the extended IDO inherits the core IDO's methods and adds custom properties).
Once you've identified a candidate IDO, load a few rows with all properties to confirm it's the right one:
curl -s "$SYTELINE_BASE_URL/load/UserNames?recordcap=3" \
-H "Authorization: $TOKEN"Omitting properties returns all properties. Seeing the actual data helps you verify you're looking at the right IDO — column names, data shapes, and values tell you a lot.
Note: Some core IDOs (e.g.,
SLItemprices) may be replaced by a custom extended version (e.g.,CMP_SLItemPrices) via extend and replace. If you get"User requires [Read] privilege for CMP_{IDO}", the system is redirecting through the extended IDO. Request permissions on the IDO named in the error.
curl -s "$SYTELINE_BASE_URL/load/IdoProperties?properties=PropertyName,DataType,PropertyClass,ColumnTableAlias,ColumnName&filter=CollectionName%20%3D%20N'SLItemprices'&recordcap=0" \
-H "Authorization: $TOKEN"PropertyClass values:
- Empty/0 = Bound to a database column
- 1 = Derived (computed via SQL expression)
- 3 = Subcollection (link to child IDO)
This is especially useful to map SQL column names to IDO property names. For example, the SQL column unit_price1 on the itemprice table maps to the IDO property UnitPrice1 on SLItemprices.
curl -s "$SYTELINE_BASE_URL/load/IdoProperties?properties=PropertyName,ColumnName,ColumnTableAlias,DataType&filter=CollectionName%20%3D%20N'SLItemprices'%20AND%20ColumnName%20%3D%20N'unit_price1'&recordcap=10" \
-H "Authorization: $TOKEN"curl -s "$SYTELINE_BASE_URL/load/IdoMethods?properties=MethodName,MethodType&filter=CollectionName%20%3D%20N'SLItemprices'&recordcap=0" \
-H "Authorization: $TOKEN"This tells you what methods are available and whether each is a stored procedure or extension class. The method name is sufficient to proceed to Step 4.
When a stored procedure has been converted to an extension class (MethodType=2), it can only be called through the IDO API, not via direct SQL EXEC.
Use the IdoMethodParameters IDO to discover the exact parameter signature of any method:
curl -s "$SYTELINE_BASE_URL/load/IdoMethodParameters?properties=Sequence,ParameterName,DataType,SpDataType,SpDataLength,SpDataScale,InputFlag,OutputFlag&filter=CollectionName%20%3D%20N'SLItemprices'%20AND%20MethodName%20%3D%20N'ItemPriceChangeSp'&orderby=Sequence&recordcap=0" \
-H "Authorization: $TOKEN"This returns every parameter with:
| Property | What it tells you |
|---|---|
Sequence |
Positional index (1-based) — determines the order in the JSON array for /invoke |
ParameterName |
Name of the parameter |
DataType |
IDO-level data type |
SpDataType |
SQL Server data type (e.g., nvarchar, decimal) |
SpDataLength / SpDataScale |
Length and scale for the SQL type |
InputFlag |
1 = input parameter |
OutputFlag |
1 = output parameter |
Parameters with both InputFlag=1 and OutputFlag=1 are IN/OUT — pass a value in, and the method writes back to the same position.
Note: A
Directionproperty is referenced in some Syteline docs but does not exist onIdoMethodParameters— you'll get"Property Direction not found". UseInputFlagandOutputFlaginstead; they convey the same information.
This is the definitive way to build an /invoke call. The parameter count and order from IdoMethodParameters must match your JSON array exactly.
For background tasks, you can also see what parameters were used in historical runs:
curl -s "$SYTELINE_BASE_URL/load/BGTaskHistories?properties=TaskName,TaskParms1,TaskParms2,CompletionStatus&filter=TaskName%20LIKE%20N'%25ItemPrice%25'&orderby=CompletionDate%20DESC&recordcap=5" \
-H "Authorization: $TOKEN"curl -s "$SYTELINE_BASE_URL/load/IdoTables?properties=TableName,TableAlias,TableType,JoinType,JoinText&filter=CollectionName%20%3D%20N'SLItemprices'&recordcap=0" \
-H "Authorization: $TOKEN"Primary keys matter for Update and Delete operations. Use SqlColumns to find them:
curl -s "$SYTELINE_BASE_URL/load/SqlColumns?properties=tableName,table_name_key,derShadowColumnName,dataType,isPrimaryKey,primaryKeyPosition&filter=tableName%20%3D%20N'itemprice_mst'%20AND%20isPrimaryKey%20%3D%201&recordcap=0" \
-H "Authorization: $TOKEN"Note: SQL table names in
SqlColumnsuse the_mstsuffix (e.g.,itemprice_mstnotitemprice). The IDO layer strips this suffix. UsederShadowColumnNameto get the actual column name.
Example result for itemprice_mst:
| Position | Column | Type |
|---|---|---|
| 1 | item |
ItemType |
| 2 | curr_code |
CurrCodeType |
| 3 | effect_date |
Date4Type |
| 4 | site_ref |
SiteType |
This compound key tells you: a price record is uniquely identified by item + currency + effective date + site. A query like DELETE FROM itemprice WHERE unit_price1 = 0 without considering effect_date could be dangerously broad.
1. What IDO do I need?
→ Search IdoCollections by name
→ Search IdoMethods by MethodName (LIKE %SpName%)
→ Search IdoTables by database table name
→ Poke around with LoadCollection (recordcap=3)
2. Is this the right IDO?
→ Load a few rows with all properties to verify
→ Check AccessAs on IdoCollections (core vs custom)
3. What properties does it have?
→ Query IdoProperties for the IDO
→ Map SQL columns ↔ IDO properties via ColumnName
4. What methods can I call?
→ Query IdoMethods for the IDO
5. What parameters does the method expect?
→ Query IdoMethodParameters (definitive)
→ Check BGTaskHistories for historical examples
6. What are the primary keys?
→ Query SqlColumns with isPrimaryKey=1
7. Call it
→ GET /load/{IDO} to query
→ POST /invoke/{IDO}?method={Method} to execute
→ POST /update/{IDO} to insert/update/delete
When you need the raw database schema (not the IDO abstraction):
curl -s "$SYTELINE_BASE_URL/load/SqlColumns?properties=tableName&filter=tableName%20LIKE%20N'%25itempric%25'&recordcap=10" \
-H "Authorization: $TOKEN"Note: Syteline tables use a
_mstsuffix in the database (e.g.,itemprice_mst). The IDO layer references them without the suffix.
curl -s "$SYTELINE_BASE_URL/load/SqlColumns?properties=tableName,table_name_key,derShadowColumnName,dataType,isPrimaryKey,primaryKeyPosition,isNullable&filter=tableName%20%3D%20N'itemprice_mst'&recordcap=0" \
-H "Authorization: $TOKEN"Key properties on SqlColumns:
| Property | What it tells you |
|---|---|
tableName |
Table name (with _mst suffix) |
table_name_key |
Composite key (usually equals tableName) |
derShadowColumnName |
The actual column name |
dataType |
Custom Syteline type (e.g., ItemType, CurrCodeType) |
isPrimaryKey |
1 = part of primary key |
primaryKeyPosition |
Position in the primary key (1-based) |
isNullable |
Whether the column allows NULL |
When you encounter an error like:
"You may not call this 'ItemPriceChangeSp' as it has been converted to custom assembly application method."
curl -s "$SYTELINE_BASE_URL/load/IdoMethods?properties=CollectionName,MethodName,MethodType&filter=MethodName%20LIKE%20N'%25ItemPriceChangeSp%25'&recordcap=10" \
-H "Authorization: $TOKEN"curl -s "$SYTELINE_BASE_URL/load/IdoMethodParameters?properties=Sequence,ParameterName,DataType,SpDataType,InputFlag,OutputFlag&filter=CollectionName%20%3D%20N'SLItemprices'%20AND%20MethodName%20%3D%20N'ItemPriceChangeSp'&orderby=Sequence&recordcap=0" \
-H "Authorization: $TOKEN"curl -s -X POST \
"$SYTELINE_BASE_URL/invoke/SLItemprices?method=ItemPriceChangeSp" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d '["param1", "param2", null, ...]'This pattern works for any stored procedure that has been converted to an extension class method.
Given a SQL script like DELETE FROM itemprice WHERE unit_price1 = 0, here's how to convert it to an API call:
curl -s "$SYTELINE_BASE_URL/load/IdoTables?properties=CollectionName,TableName,TableType&filter=TableName%20%3D%20N'itemprice'%20AND%20TableType%20%3D%203&recordcap=10" \
-H "Authorization: $TOKEN"Filter TableType=3 to find IDOs where itemprice is the primary base table.
If multiple IDOs share the primary table, check which is core vs. custom:
curl -s "$SYTELINE_BASE_URL/load/IdoCollections?properties=CollectionName,AccessAs&filter=CollectionName%20%3D%20N'SLItemprices'&recordcap=1" \
-H "Authorization: $TOKEN"For deletes, it usually doesn't matter whether you use the core IDO or the CMP_-extended version — the delete hits the same base table.
curl -s "$SYTELINE_BASE_URL/load/IdoProperties?properties=PropertyName,ColumnName,ColumnTableAlias,DataType&filter=CollectionName%20%3D%20N'SLItemprices'%20AND%20ColumnName%20%3D%20N'unit_price1'&recordcap=10" \
-H "Authorization: $TOKEN"Result: SQL column unit_price1 → IDO property UnitPrice1.
curl -s "$SYTELINE_BASE_URL/load/SqlColumns?properties=derShadowColumnName,dataType,primaryKeyPosition&filter=tableName%20%3D%20N'itemprice_mst'%20AND%20isPrimaryKey%20%3D%201&recordcap=0" \
-H "Authorization: $TOKEN"The itemprice table has a 4-column composite key: item, curr_code, effect_date, site_ref. This means DELETE WHERE unit_price1 = 0 without considering effect_date is likely too broad — stop and confirm scope with the user.
curl -s "$SYTELINE_BASE_URL/load/SLItemprices?properties=Item,CurrCode,EffectDate,UnitPrice1&filter=UnitPrice1%20%3D%200&recordcap=10" \
-H "Authorization: $TOKEN"curl -s -X POST \
"$SYTELINE_BASE_URL/update/SLItemprices" \
-H "Authorization: $TOKEN" \
-H "Content-Type: application/json" \
-d '{"Items":[{"Action":"Delete","Properties":{"Item":"WIDGET-A","CurrCode":"USD","EffectDate":"2026-01-01","SiteRef":"{SITE_FROM_USER_SCOPE}"}}]}'Use the key values from the LoadCollection to build each Delete item.