First endpoint
Create and verify a Postgres source and destination with a complete two-row read/write example
What you will build
This walkthrough creates two workspace-scoped Postgres endpoints: an Ingress source that reads two orders and an Egress destination that writes those records into a separate test table. You will install the matching capabilities, prepare the database fixtures, configure both endpoints and verify the results in PostgreSQL. All steps are included here.
A data endpoint gives a concrete target a reusable name in Semogram. The plugin installation holds the database connection and credentials; the endpoint holds the selected schema/table or query. Projects in the same workspace can reference it, subject to permissions. Saving either endpoint does not execute the transfer.
The diagram shows the three available directions. This walkthrough exercises Ingress and Egress; ontology materialization uses a separate fact-store capability and project ontology binding rather than the two business-table endpoints below.
Directions and supported operations
| Direction | Capability and contract | Behavior |
|---|---|---|
| Ingress: database → Semogram | read, source_stream or source_query | Read a table or a reviewed SQL query; supported record reads can select, filter, sort and paginate |
| Egress: Semogram → database | write, write | Send pipeline records to an output table |
| Materialization: ontology → database | ontology-store, ontology_fact_store | Store ontology facts and read them through the ontology adapter |
Each endpoint selects one installed capability. Create separate source, destination and fact-store endpoints even when they connect to the same database. A source endpoint is not automatically a destination.
The writer implements append, replace, upsert, update and delete. Keyed mutations require an actual database primary key; a primary-key hint on an endpoint does not create a constraint. Replacement recreates the table. Commits are per row, not one transaction covering a whole run. Policy writes reject foreign-key relationships and triggers.
Published-contract limitation: the current catalog target advertises append, upsert and overwrite, while the writer uses replace rather than overwrite. Do not treat these names as interchangeable. The complete destination example below uses append, which both support. Other mutations require a compatible installed contract and execution path; changing JSON alone does not enable them.
Plugin used
This example uses the Postgres read capability for the source and the Postgres write capability for the destination. Install and select each capability separately. Installation steps for this example are included below. The Postgres installation guide provides optional further detail. Connection details and credentials stay on the installation; the endpoint selects a particular target through that installed capability.
What you need
- A Semogram account with workspace access and permission to manage plugin installations and endpoints
- A reachable PostgreSQL test database, its host/port/database name, TLS settings and protected credentials
- A database identity allowed to create the fixture tables and insert sample data; source access to read the input, and destination access to create/alter/write the output table
- A SQL client to prepare and inspect the fixture and a project in this workspace to run the test pipeline
The external database must already exist. Installing Postgres does not provision it or grant database privileges. Read and write installations can use separate database users. Use a fresh test database or change all fixture names consistently if these tables already exist.
Example names and targets
| Resource | Example | Meaning |
|---|---|---|
| Source database table | public.orders | Table orders inside PostgreSQL schema public; created below |
| Destination database table | public.verified_orders | Separate output table; created in the write example |
| Source endpoint name | orders | Workspace label chosen in Semogram |
| Destination endpoint name | verified_orders | Workspace label chosen in Semogram |
| Endpoint namespace | sales | Semogram grouping label; it does not create a database schema |
| Record key | order_id | Primary-key column defined by the fixture SQL |
Read example: create the source endpoint
Install and configure the plugin
- Open Plugins in this workspace and select Explore.
- Find Postgres, inspect its publisher/version and select its read capability.
- Name the installation and fill its connection settings using your actual external-system details.
- Save and run the supported connection check. Fix any reported error before creating the endpoint.
Example installation configuration:
Open workspace Plugins → Explore, choose the matching capability and fill its installation settings. Enter values in the labeled controls rather than pasting the whole JSON object.
| UI field | Example value |
|---|---|
| Host | YOUR_DATABASE_HOST |
| Port | 5432 |
| Database | YOUR_DATABASE |
| User | YOUR_DATABASE_USER |
| Password | YOUR_PASSWORD |
| Ssl | Enabled |
Nested labels above identify the containing group. Lists use the form’s list controls; open-ended objects use its object editor. Labels and available options follow the installed version’s contract. Enter credentials in the protected fields and review the selected installation before saving.
In the platform assistant or your connected MCP assistant, ask:
Install the plugin described on this page in this workspace. Discover its catalog entry, select the matching capability and propose the installation using the connection settings shown here. Ask me to enter credentials in protected installation fields. Show the selected plugin/version, capability and non-secret settings before saving.Replace placeholders with real accessible resources. The assistant prepares the operation; inspect its proposed inputs and result.
Use plugin_catalog_list / plugin_catalog_get to obtain the discovery ID and matching capability class (reads, writes or factStores). Call plugin_installation_create with the arguments below through an authenticated MCP connection. The workspace comes from that connection. Enter credentials through an authorized protected configuration path; do not send real secrets as conversational prompt text.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "plugin_installation_create",
"arguments": {
"capabilityClass": "<MATCHING_CAPABILITY_CLASS>",
"discoveryId": "<DISCOVERY_ID_FROM_CATALOG>",
"name": "<INSTALLATION_NAME>",
"config": {
"host": "YOUR_DATABASE_HOST",
"port": 5432,
"database": "YOUR_DATABASE",
"user": "YOUR_DATABASE_USER",
"password": "YOUR_PASSWORD",
"ssl": true
},
"idempotencyKey": "<UNIQUE_KEY_FOR_THIS_INSTALLATION>"
}
}
}This operation has no standalone public /api/v1 plugin-installation/catalog route in the current implementation. Use the UI or MCP methods shown here.
This operation has no standalone public /api/v1 plugin-installation/catalog route in the current implementation. Use the UI or MCP methods shown here.
Replace every YOUR_… value. Enter credentials only in protected installation configuration. The configuration above is separate from the endpoint target below; selecting a target does not create or authenticate the connection.
Prepare example data
In a test database, use your database's SQL client to create a tiny example table. The configured database user must have permission to read it.
CREATE TABLE public.orders (
order_id integer PRIMARY KEY,
total numeric(12,2),
placed_at timestamptz
);
INSERT INTO public.orders VALUES
(1, 120.00, '2026-01-01T10:00:00Z'),
(2, 75.50, '2026-01-02T10:00:00Z');Use a fresh test table/database if public.orders already exists. If you use a different table, update the target below to match it.
Use the assistant
Open Data Endpoints → New data endpoint in the workspace. Describe your actual target and choose a name for the endpoint. For the example above, you could ask:
Create a source endpoint named orders in namespace sales.
Use our installed Postgres read capability with contract source_stream
and set these target fields:
Schema: public
Table: orders
Review the proposed connection and target before saving.Replace example values with your own. Give the assistant the installed connection reference; keep credentials in protected installation settings.
Configure manually
Choose Edit manually, select the matching installed capability and configure:
| Field | Value |
|---|---|
| Name | orders |
| Namespace | sales |
| Direction / role | Ingress / source |
| Contract | source_stream |
Open workspace Data Endpoints → New data endpoint → Edit manually, choose the direction and installed capability described in this example, then fill the target fields. Enter values in the labeled controls rather than pasting the whole JSON object.
| UI field | Example value |
|---|---|
| Schema | public |
| Table | orders |
Nested labels above identify the containing group. Lists use the form’s list controls; open-ended objects use its object editor. Labels and available options follow the installed version’s contract. Review the endpoint name, direction, capability and selected target before saving.
In the platform assistant or your connected MCP assistant, ask:
Create the endpoint described on this page using these settings:
name: <ENDPOINT_NAME_FROM_THIS_EXAMPLE>
namespace: <ENDPOINT_NAMESPACE_FROM_THIS_EXAMPLE>
role: source
contractKind: source_stream
target / schema: public
target / table: orders
pluginCapabilityInstallationId: <INSTALLED_CAPABILITY_UUID>
Use the actual installed capability and the endpoint name/namespace selected in this example. Show the proposed direction, connection and target before saving. Keep credentials on the installation.Replace placeholders with real accessible resources. The assistant prepares the operation; inspect its proposed inputs and result.
Use a workspace API key with endpoints:write. Set SEMOGRAM_API_KEY in your shell; replace resource placeholders with real IDs. This is an HTTP resource request, not an MCP JSON-RPC message.
curl --request POST "https://platform.semogram.com/api/v1/data-endpoints" \
--header "Authorization: Bearer ${SEMOGRAM_API_KEY}" \
--header "Idempotency-Key: <UNIQUE_KEY_FOR_THIS_ENDPOINT>" \
--header "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"name": "<ENDPOINT_NAME_FROM_THIS_EXAMPLE>",
"namespace": "<ENDPOINT_NAMESPACE_FROM_THIS_EXAMPLE>",
"role": "source",
"contractKind": "source_stream",
"target": {
"schema": "public",
"table": "orders"
},
"pluginCapabilityInstallationId": "<INSTALLED_CAPABILITY_UUID>"
}
JSONCall source_create with the arguments below through an authenticated workspace MCP connection. Replace the name/namespace placeholders with the labels chosen in this example and use the actual installed capability UUID. Set the role/contract to the direction described here; the workspace is resolved from the connection. This configures an endpoint and does not execute a read or write.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "source_create",
"arguments": {
"name": "<ENDPOINT_NAME_FROM_THIS_EXAMPLE>",
"namespace": "<ENDPOINT_NAMESPACE_FROM_THIS_EXAMPLE>",
"role": "source",
"contractKind": "source_stream",
"target": {
"schema": "public",
"table": "orders"
},
"pluginCapabilityInstallationId": "<INSTALLED_CAPABILITY_UUID>",
"idempotencyKey": "<UNIQUE_KEY_FOR_THIS_ENDPOINT>"
}
}
}Set the primary-key hint to order_id after checking uniqueness and nulls. Add a useful description, owner and expected freshness. Save in the workspace. Inspect the installed version’s contract before adding optional settings.
Verify the source read
- Open the saved endpoint and run its supported connection check and schema inspection.
- Read a small sample through the supported preview. If the connector has no preview, select a project, open Pipeline Studio and create a pipeline with a source node referencing this endpoint.
- Configure a bounded test input using the connector's supported settings, validate the pipeline, save a version and run it.
- Inspect returned records or the completed run's output. Compare expected keys and values with the example fixture before scheduling anything.
Compare order IDs, totals, timestamps and nulls with the database. One table read does not prove access to other tables.
Check connectivity, target validity and actual data separately. Saving does not import records or schedule execution.
Write example: copy two orders into a test output table
This example uses the two-row public.orders fixture created above. The source endpoint is named orders; the destination will be named verified_orders, grouped under namespace sales, and will target a different physical table, public.verified_orders. Endpoint names are Semogram labels; public and the table names are PostgreSQL objects.
- In workspace Plugins → Explore, select Postgres → write and install it. Enter the same host, port, database and TLS settings shown above, with a database user authorized for the output table. Read and write installations can use different least-privilege users.
- In your test database SQL client, create an empty output table:
CREATE TABLE public.verified_orders (
order_id integer PRIMARY KEY,
total numeric(12,2),
placed_at timestamptz
);- Grant the installation user the required schema and output-table access. The writer also performs table/schema setup; its connection needs permission to create tables and to alter the test output table. The writer enables row-level security on that table; use its owner or an explicitly authorized database identity when verifying the output. Keep this fixture in a test database where those operations are authorized.
- Open workspace Data Endpoints → New data endpoint → Edit manually. Choose name
verified_orders, namespacesales, Egress (roledestination), the installed Postgres write capability and contractwrite. - Set the target and save:
Open workspace Data Endpoints → New data endpoint → Edit manually, choose the direction and installed capability described in this example, then fill the target fields. Enter values in the labeled controls rather than pasting the whole JSON object.
| UI field | Example value |
|---|---|
| Schema | public |
| Table | verified_orders |
| Write mode | append |
Nested labels above identify the containing group. Lists use the form’s list controls; open-ended objects use its object editor. Labels and available options follow the installed version’s contract. Review the endpoint name, direction, capability and selected target before saving.
In the platform assistant or your connected MCP assistant, ask:
Create the endpoint described on this page using these settings:
name: <ENDPOINT_NAME_FROM_THIS_EXAMPLE>
namespace: <ENDPOINT_NAMESPACE_FROM_THIS_EXAMPLE>
role: destination
contractKind: write
target / schema: public
target / table: verified_orders
target / writeMode: append
pluginCapabilityInstallationId: <INSTALLED_CAPABILITY_UUID>
Use the actual installed capability and the endpoint name/namespace selected in this example. Show the proposed direction, connection and target before saving. Keep credentials on the installation.Replace placeholders with real accessible resources. The assistant prepares the operation; inspect its proposed inputs and result.
Use a workspace API key with endpoints:write. Set SEMOGRAM_API_KEY in your shell; replace resource placeholders with real IDs. This is an HTTP resource request, not an MCP JSON-RPC message.
curl --request POST "https://platform.semogram.com/api/v1/data-endpoints" \
--header "Authorization: Bearer ${SEMOGRAM_API_KEY}" \
--header "Idempotency-Key: <UNIQUE_KEY_FOR_THIS_ENDPOINT>" \
--header "Content-Type: application/json" \
--data-binary @- <<'JSON'
{
"name": "<ENDPOINT_NAME_FROM_THIS_EXAMPLE>",
"namespace": "<ENDPOINT_NAMESPACE_FROM_THIS_EXAMPLE>",
"role": "destination",
"contractKind": "write",
"target": {
"schema": "public",
"table": "verified_orders",
"writeMode": "append"
},
"pluginCapabilityInstallationId": "<INSTALLED_CAPABILITY_UUID>"
}
JSONCall source_create with the arguments below through an authenticated workspace MCP connection. Replace the name/namespace placeholders with the labels chosen in this example and use the actual installed capability UUID. Set the role/contract to the direction described here; the workspace is resolved from the connection. This configures an endpoint and does not execute a read or write.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "source_create",
"arguments": {
"name": "<ENDPOINT_NAME_FROM_THIS_EXAMPLE>",
"namespace": "<ENDPOINT_NAMESPACE_FROM_THIS_EXAMPLE>",
"role": "destination",
"contractKind": "write",
"target": {
"schema": "public",
"table": "verified_orders",
"writeMode": "append"
},
"pluginCapabilityInstallationId": "<INSTALLED_CAPABILITY_UUID>",
"idempotencyKey": "<UNIQUE_KEY_FOR_THIS_ENDPOINT>"
}
}
}- Select a project in this workspace and open Pipeline Studio. Create a pipeline with an ingress node referencing
ordersand an egress node referencingverified_orders; connect the source output to the destination input. Use only the two fixture rows. Inspect the resolved target, append mode and applicable write policy/permissions; validate, save a version and execute once. - Inspect the completed run and query the external table:
SELECT order_id, total, placed_at
FROM public.verified_orders ORDER BY order_id;Expect IDs 1 and 2 with totals 120.00 and 75.50. Also read the original public.orders table to confirm the source was unchanged. A failed run may have committed some rows: inspect the output before retrying. Repeating append with these primary keys can fail with a duplicate-key error; it is not an automatic upsert. To repeat this fixture, clear only the dedicated test output table using your database tools, then run once again.
A prompt alternative is: “Create an Egress endpoint named verified_orders in namespace sales using the installed Postgres write capability, contract write, and target schema public, table verified_orders, writeMode append.” Review the actual capability, target and policy before executing the pipeline.
Manage the endpoint
For a reviewed SQL source, select the supported source_query contract and use a target such as {"query":"SELECT order_id, total FROM public.orders LIMIT 100"}. Query targets differ from table targets.
Keep credentials on the installation. Review consumers before replacing capabilities, changing targets or deleting endpoints.
FAQ
Why does verification fail?
Check host reachability, TLS, database/schema/table spelling and the selected capability. Read and write grants are different. For output failures, also check table ownership/alter permissions, row-level security and duplicate primary keys. Inspect any partially written output before retrying.
Can another project use it?
Yes, within the same workspace and subject to permissions. The endpoint remains workspace-scoped.
Did creating the endpoint copy the data?
No. The endpoint stores configuration. The read preview or pipeline retrieves records; the egress execution writes them. Scheduling is another explicit action.
What comes after verification?
Use sources in a bounded pipeline, destinations in a supported write flow, and stores in ontology bindings. Inspect real output before scheduling recurring work.