Configure an API Profile as a source for data integration tasks to extract data from custom APIs using standard API profile definitions.
This connection type supports the following task types:
This connection can be used in a Data Migration.
| Usable as Source | Usable as Target | Usable as Incremental Source | Usable as Incremental Target |
|---|---|---|---|
| ✔ | ✔ | ✔ | ❌ |
| Template Name | Description |
|---|---|
| Profile | A connection string containing the path to the API Profile .apip file. |
| Profile with Profile Settings | A connection string containing the path to the API Profile .apip file and additional profile configuration settings ProfileSettings=[Profile Configuration Settings]. |
This covers the core patterns and operational rules needed to successfully build, deploy, and troubleshoot API Profiles for Loome Integrate.
An API Profile allows Loome Integrate to consume REST APIs as relational tables without custom code.
The profile consists of:
Loome currently supports read operations only. Insert, Update, and Delete implementations are ignored except for table-classification stubs.
other:xPath on every response fieldallownull() for sparse JSON fieldscolumnsize="65535" for long text_query.criteria for incremental filteringVerbosity=5 during developmentUsing VS Code: 1. Run Create New API Profile task. 2. A profile structure is generated:
MyProfile/
│
├── src/
├── build/
├── debug/
└── README.md
Purpose of folders:
| Folder | Purpose |
|---|---|
| src | RSD and RSB source files |
| build | APIP output |
| debug | Logs, cache, OAuth storage |
| README | Profile documentation |
Each API endpoint becomes an RSD file. An RSD contains:
Schema:
<api:info title="Users">
<attr name="Id" xs:type="integer" other:xPath="id"/>
<attr name="Name" xs:type="string" other:xPath="name"/>
</api:info>
Defines: - SQL table name - Columns - Data types - JSON extraction paths
Execution Logic:
<api:script method="GET">
<api:set attr="uri"
value="[_connection.BaseURL]/users"/>
<api:set attr="RepeatElement" value="/"/>
<api:call op="apisadoExecuteJSONGet">
<api:push/>
</api:call>
</api:script>
Defines: - Endpoint URL - HTTP method - JSON location - Returned rows
The exposed SQL table name comes from:
<api:info title="Users">
and not from:
users.rsd
Changing the file name does not rename the table.
One endpoint is equal to one table. Avoid combining unrelated endpoints in one file.
Recommended approach:
Basic Mapping:
{
"id": 1,
"name": "ABC"
}
Mapping:
<attr name="Id" other:xPath="id"/>
<attr name="Name" other:xPath="name"/>
JSON:
{
"contact": {
"email": "abc@test.com"
}
}
Mapping:
<attr name="Email"
other:xPath="contact/email"/>
Deep Nesting
<attr name="Latitude"
other:xPath="address/geo/lat"/>
Arrays
“tags”: [“A”,“B”]
<attr name="PrimaryTag"
other:xPath="tags/0"/>
You can make inline transformations.
Example:
<api:set attr="Email"
value="[Email | trim() | tolower()]"/>
Useful formatters:
| Formatter | Purpose |
|---|---|
| trim() | Remove spaces |
| tolower() | Lowercase |
| toupper() | Uppercase |
| replace() | Replace values |
| split() | Extract pieces |
| substring() | Partial text |
| def() | Default value |
| capitalize() | First letter uppercase |
| equals() | Conditional comparison |
For example:
<api:set attr="Status"
value="[Status | equals('Active','1','0')]"/>
Always implement pagination when available.
API pattern:
?limit=500&offset=1000
Configuration:
<api:set attr="EnablePaging" value="true"/>
<api:set attr="pageoffsetparam"
value="offset"/>
<api:set attr="pagesizeparam"
value="limit"/>
<api:set attr="pagesize"
value="500"/>
API pattern:
?page=2&limit=500
Configuration:
<api:set attr="EnablePaging" value="true"/>
<api:set attr="pagenumberparam"
value="page"/>
<api:set attr="pagesizeparam"
value="limit"/>
Loome pushes SQL filters to the profile.
Example:
WHERE ModifiedDate > '2025-01-01'
The profile should extract this filter using:
[_query.criteria]
Then pass the value to the API endpoint.
Benefits:
Query slicing is the preferred approach when one endpoint depends on values from another.
Key Rules:
{ColumnName} inside URIs.[ColumnName] elsewhere.other:filter="{ColumnName}"Example:
Reservations
↓
ReservationDailyRates
The child table automatically loops through parent IDs.
Child Configuration:
<api:info
title="ReservationDailyRates"
other:queryslicercolumn="ReservationId"
other:slicetable="Reservations"
other:sliceforeignkey="Id">
Column:
<attr name="ReservationId"
other:filter="{ReservationId}"/>
URI:
<api:set attr="uri"
value=".../reservations/{ReservationId}/dailyRates"/>
When child arrays must become rows.
Example JSON:
{
"batch": {
"transactions": [...]
}
}
Configuration:
<api:set attr="DataModel"
value="FLATTENEDDOCUMENTS"/>
<api:set attr="JSONPath"
value="$.value;$.value.Transactions"/>
Use absolute paths:
other:xPath="/json/value/Transactions/Amount"
Never:
other:xPath="Amount"
API Key
<api:set attr="http.header:Authorization"
value="[_connection.APIKey | prefix('Bearer ')]"/>
Basic Authentication
<api:set attr="auth.scheme"
value="basic"/>
OAuth 2.0
Example:
AuthScheme=OAuth;
OAuthVersion=2.0;
OAuthGrantType=CLIENT;
OAuthClientId=...
OAuthClientSecret=...
OAuthTokenURL=...
Custom OAuth flows can be implemented in a separate:
GetOAuthAccessToken.rsb
You can then build the profile.
Run:
Build API Profile: <Profile Name>
Output:
build/MyProfile.apip
In Loome Integrate, go to Connections at the top-right dropdown menu.
Choose ‘API Profile’ in the connector list.
Choose whether it will be available in all projects or only in your chosen projects.
Provide your connection string. In Loome, replace the profile in the connection string with the name of your own API profile and profile settings.
Basic connection:
Profile=C:\Profiles\MyProfile.apip;
With settings:
Profile=C:\Profiles\MyProfile.apip;
ProfileSettings=
'BaseUrl=https://api.example.com;
APIKey=xxxx';
Choose an agent and submit the connection.
Logfile=C:\debug\api-profile.log;
Verbosity=5;
Location=C:\debug;
CacheLocation=C:\debug;
These are the most common causes of production failures.
Silent Row Loss During Slicing
<api:set attr="BranchID" value="[BranchID]"/>Column Shifting / Incorrect Data
<attr other:xPath="..."/> for response fields.<api:set attr="SomeField" value="[SomeField | allownull()]"/> before: api:push/Long Text Truncation
<attr
name="Description"
xs:type="string"
columnsize="65535"/>
Table vs View
<api:script method="GET">Expected API Errors
<api:catch code="*"/> inside: <api:call>
You can check these fields when troubleshooting for these issues:
other:xPathallownull()