This chapter explains how to create a basic INTERA Integration Module, define configuration parameters, expose DataSources, test the integration in a trial environment, and prepare for future publication in the INTERA Online Store.
The goal of your first integration is not to cover every possible feature. The goal is to build a small, valid Integration Module that INTERA can load, configure, and call successfully.
A typical first integration should:
- declare basic integration metadata;
- define the configuration fields required to connect to the external system;
- expose at least one DataSource;
- return predictable test data;
- handle basic errors clearly;
- run successfully in an INTERA trial environment.
Prerequisites #
Before building an INTERA integration, you should have access to an INTERA developer or trial environment.
You will need:
- access to INTERA Core or an INTERA trial environment;
- a working development machine;
- Node.js runtime supported by your INTERA environment;
- access to the external system you want to integrate;
- API credentials, database credentials, file access, or test data;
- basic knowledge of JavaScript or TypeScript;
- basic understanding of JSON or YAML configuration;
- permission to read data from the external system.
For your first integration, we recommend using a safe test source. This can be a demo API, a test database, a sample CSV file, or mock data returned directly from the integration.
Do not start with a production system unless you already understand the integration model and have read-only access configured.
A first integration should usually be read-only.
Recommended first integration types:
- simple API integration;
- static demo DataSource;
- CSV/file-based integration;
- read-only SQL view integration.
Avoid starting with:
- write-back actions;
- complex authentication flows;
- large database imports;
- unstable file formats;
- multi-system reconciliation logic;
- production credentials.
The purpose of the first integration is to confirm that INTERA can load your module, create an Integration Instance, call a DataSource, and receive structured data.
Create a new integration #
An Integration Module is usually created as a separate folder or package. The exact packaging format may depend on the INTERA version you are targeting, but the basic idea is always the same: the module must expose a manifest and one or more supported capabilities.
A simple integration folder may look like this:
my-first-integration/
├── dist/
│ └── index.js
├── README.md
└── package.json
The main entry point should export the integration definition.
A minimal example may look like this:
module.exports = {
manifest: {
id: "my_first_integration",
name: "My First Integration",
version: "1.0.0",
kind: "direct_api",
capabilities: ["datasource"],
defaultCacheTtlSec: 300
},
dataSources: []
};
The manifest tells INTERA what the integration is and what it can provide.
Important manifest fields:
id Unique technical identifier for the integration.
name Human-readable integration name.
version Integration version.
kind General integration type.
capabilities Features provided by the integration.
defaultCacheTtlSec Default cache lifetime for DataSource results.
Example kind values may include:
direct_api
readonly_api
legacy
sql
file
Example capabilities may include:
datasource
entity_provider
sync
action
For a first integration, start with the smallest possible module:
- one manifest;
- one configuration schema;
- one DataSource;
- one predictable response.
Do not add entity synchronization, write-back actions, or complex mapping until the first DataSource works.
Define configuration parameters #
Configuration parameters describe what information INTERA needs in order to create an Integration Instance.
The Integration Module is reusable. The Integration Instance is the configured connection created from that module.
For example, a module called my_billing_api may be used to create several instances:
Billing API - Production
Billing API - Test
Billing API - Cyprus Company
Billing API - UK Company
Each instance may have different configuration values.
Typical configuration parameters include:
- API base URL;
- API key;
- username;
- password;
- tenant ID;
- company ID;
- database host;
- database name;
- file path;
- SFTP server;
- default currency;
- default timezone;
- sync interval.
A simple configuration schema may look like this:
module.exports = {
manifest: {
id: "my_first_integration",
name: "My First Integration",
version: "1.0.0",
kind: "direct_api",
capabilities: ["datasource"],
defaultCacheTtlSec: 300
},
configSchema: [
{
key: "baseUrl",
label: "API Base URL",
type: "string",
required: true
},
{
key: "apiKey",
label: "API Key",
type: "secret",
required: true
},
{
key: "tenantId",
label: "Tenant ID",
type: "string",
required: false
}
],
dataSources: []
};
Configuration fields should be clear and stable. Avoid exposing internal technical options that a normal INTERA administrator cannot understand.
Good configuration labels:
API Base URL
API Key
Tenant ID
Company Code
Default Currency
SFTP Folder Path
Read-only Database Name
Poor configuration labels:
Param 1
Token thing
Internal mode
Use old logic
Temporary flag
Debug only
Sensitive values such as API keys, passwords, tokens, and private keys should be marked as secrets and handled according to INTERA’s credential storage rules.
A good configuration schema should answer three questions:
1. What does the administrator need to enter?
2. Which fields are required?
3. Which values must be protected as secrets?
For your first integration, keep configuration simple. If you are using mock data, you may not need any configuration fields at all.
Define DataSources #
A DataSource is a named data endpoint exposed by your Integration Module.
It allows INTERA to request a specific dataset from the external system. A DataSource may return customers, invoices, payments, tickets, vessel positions, active services, usage records, or any other structured data that INTERA dashboards, Metrics, or rules can use.
For your first integration, create one simple DataSource.
Example:
module.exports = {
manifest: {
id: "my_first_integration",
name: "My First Integration",
version: "1.0.0",
kind: "direct_api",
capabilities: ["datasource"],
defaultCacheTtlSec: 300
},
configSchema: [
{
key: "baseUrl",
label: "API Base URL",
type: "string",
required: false
}
],
dataSources: [
{
id: "status_summary",
name: "Status Summary",
getData: async (params, context) => {
return {
status: "ok",
source: "my_first_integration",
generatedAt: new Date().toISOString(),
metrics: {
activeCustomers: 128,
openTickets: 7,
overdueInvoices: 3
}
};
}
}
]
};
This example does not connect to a real external system. It simply returns structured test data. This is a useful first step because it confirms that INTERA can load the integration and call the DataSource.
Once the basic DataSource works, you can replace the mock data with a real external call.
Example API-based DataSource:
dataSources: [
{
id: "customers",
name: "Customers",
getData: async (params, context) => {
const baseUrl = context.config.baseUrl;
const apiKey = context.config.apiKey;
const response = await fetch(`${baseUrl}/customers`, {
headers: {
Authorization: `Bearer ${apiKey}`
}
});
if (!response.ok) {
throw new Error(`External API error: ${response.status}`);
}
const customers = await response.json();
return {
items: customers,
count: customers.length,
generatedAt: new Date().toISOString()
};
}
}
]
A good DataSource should have:
- a stable technical ID;
- a clear human-readable name;
- predictable response structure;
- documented input parameters;
- clear error handling;
- reasonable limits;
- safe use of credentials;
- consistent date and timezone handling.
DataSources should be designed around business use cases, not around raw external system tables.
For example, instead of exposing this:
raw_invoice_table_dump
Prefer this:
invoices
overdue_invoices
invoice_summary
payments_received
customer_balance
A DataSource may accept parameters from INTERA.
Common parameters include:
from
to
limit
assetId
customerId
status
currency
productCode
period
Example:
getData: async (params, context) => {
const from = params.from;
const to = params.to;
const status = params.status || "open";
return {
paramsUsed: { from, to, status },
items: []
};
}
For a production integration, always validate parameters before using them in API calls, file paths, or database queries.
Publish your Integration in the Online Store #
This section is reserved for the future INTERA Online Store.
In future versions, developers will be able to submit Integration Modules for review and distribution through the INTERA Online Store. The Online Store will allow INTERA customers to discover, install, configure, and update approved integrations.
Planned publication flow:
1. Prepare the integration package.
2. Include required metadata and documentation.
3. Provide sample configuration.
4. Provide sample data or test environment access.
5. Declare supported INTERA versions.
6. Submit the integration for review.
7. Pass technical and security validation.
8. Publish the integration in the Online Store.
9. Maintain versions and updates.
A future Online Store submission may require:
- integration name and description;
- developer or company name;
- supported external system versions;
- integration capabilities;
- configuration schema;
- DataSource documentation;
- Entity Provider documentation, if supported;
- screenshots or usage examples;
- security notes;
- changelog;
- support contact;
- license or pricing model.
Until the Online Store is available, integrations may be installed directly in a developer or trial environment according to the current INTERA deployment process.
Developers should still write integrations as if they will be reviewed later. This means using clear names, stable IDs, safe credential handling, good documentation, and predictable behavior.
Test sync in your trial environment #
After creating your Integration Module, test it inside an INTERA trial or developer environment.
The purpose of testing is to confirm that INTERA can:
- discover the integration;
- read the manifest;
- create an Integration Instance;
- save configuration values;
- call DataSources;
- receive valid data;
- display or use returned values;
- report errors clearly.
For a DataSource-only integration, the basic test flow is:
1. Install or place the Integration Module in the expected integrations directory.
2. Start or restart INTERA Core.
3. Confirm that the integration appears in the integration catalog.
4. Create an Integration Instance.
5. Enter configuration parameters.
6. Save the instance.
7. Call the DataSource.
8. Check the returned data.
9. Check logs for errors or warnings.
10. Fix issues and retest.
If your integration supports Entity Sync, the test flow should also include synchronization.
Entity Sync is used when INTERA needs to import and maintain local business objects such as customers, vessels, products, contracts, services, suppliers, trucks, employees, or sites.
A typical Entity Sync test flow is:
1. Confirm that the integration declares an Entity Provider.
2. Create an Integration Instance with valid configuration.
3. Run manual sync from the trial environment.
4. Confirm that entities are imported.
5. Confirm that each entity has a stable external key.
6. Confirm that repeated sync does not create duplicates.
7. Confirm that changed external values update correctly.
8. Confirm that missing or inactive external records are handled correctly.
9. Confirm that sync errors are visible and understandable.
A synchronized entity should include a stable key. Without stable external identifiers, INTERA cannot reliably map external records to local Assets.
Example entity sync result:
[
{
"id": "CUST-1001",
"name": "Example Customer Ltd",
"status": "active",
"currency": "EUR",
"updatedAt": "2026-07-17T10:30:00Z"
},
{
"id": "CUST-1002",
"name": "Another Customer Ltd",
"status": "active",
"currency": "USD",
"updatedAt": "2026-07-17T10:30:00Z"
}
]
The trial environment should be used to test both successful and failed cases.
Recommended test cases:
- valid configuration;
- missing required configuration;
- invalid API key;
- unreachable API URL;
- empty response;
- malformed response;
- large response;
- date range filter;
- repeated sync;
- inactive or missing external records;
- external API rate limit;
- timeout.
A good integration should fail clearly. For example, this is useful:
Cannot connect to Billing API. The API key was rejected by the external system.
This is not useful:
Error.
When testing, check:
- returned data shape;
- timestamps;
- time period filters;
- secret handling;
- logs;
- duplicate records;
- response time;
- error messages;
- behavior after restart.
Your first integration is complete when INTERA can load it, create an Integration Instance, call at least one DataSource, and return predictable data in the trial environment.
After that, you can expand the integration with additional DataSources, Entity Providers, Asset Mapping support, Metrics, error states, and role-package-specific behavior.