Usage Examples
This page shows the most common API workflows end to end, with ready-to-run cURL examples. It is not a complete endpoint reference: for all endpoints, parameters, and schemas, see the OpenAPI Specification.
All requests are authenticated with an API key in the x-api-key header.
See Authentication for how to create one and export it as ENTROPY_DATA_API_KEY, as the examples below assume.
The examples build on each other and can be run in order: a marketing team publishes a Customer Cohorts data product on Snowflake, specified by a data contract, enriched with semantics, example data, and test results.
Most write endpoints follow the same pattern: PUT /api/<resource>/:id creates the resource or replaces it if it already exists.
This makes calls idempotent, so a CI/CD pipeline or sync job can safely re-send the same payload on every run.
The id is your own stable identifier, such as a UUID, URN, or slug. It must be a valid path segment, so no / or URI allowed.
Set up teams
Teams own data products, data contracts, and source systems, so create them first.
The same endpoint models domains and other organizational units, distinguished by the type attribute.
Reference a team from other resources by the id you choose here, not by its internal UUID.
curl --request PUT https://api.entropy-data.com/api/teams/marketing \
--header "x-api-key: $ENTROPY_DATA_API_KEY" \
--header "content-type: application/json" \
--data @- << EOF
{
"id": "marketing",
"name": "Marketing",
"type": "Team",
"description": "This is the marketing team",
"members": [
{
"emailAddress": "alice@example.com",
"role": "Owner"
}
]
}
EOF
See the Teams endpoints in Swagger, and Domains & Teams for the concept.
Register a data contract
A data contract captures the schema, semantics, quality expectations, and ownership of a dataset, following the Open Data Contract Standard (ODCS).
The request body is the JSON representation of the ODCS YAML structure.
Ownership is mandatory: set team.name (ODCS 3.1.0+), a custom property owner, or domain to a valid team id, otherwise the request is rejected with 422.
Here, the contract is owned by the marketing team created above.
curl --request PUT https://api.entropy-data.com/api/datacontracts/customer-cohorts \
--header "x-api-key: $ENTROPY_DATA_API_KEY" \
--header "content-type: application/json" \
--data @- << EOF
{
"apiVersion": "v3.1.0",
"kind": "DataContract",
"id": "customer-cohorts",
"name": "Customer Cohorts",
"version": "1.0.0",
"status": "active",
"description": {
"purpose": "A table with customer cohorts and their properties",
"usage": "Max. 10x queries per day",
"limitations": "Not suitable for real-time use cases"
},
"servers": [
{
"server": "production",
"type": "snowflake",
"account": "lmtrwxs-xn14859",
"database": "MARKETING_DB",
"schema": "CUSTOMER_COHORTS"
}
],
"schema": [
{
"name": "customer_cohorts",
"physicalType": "table",
"properties": [
{
"name": "customer_id",
"logicalType": "string",
"description": "Unique customer identifier.",
"required": true,
"primaryKey": true
},
{
"name": "cohort_name",
"logicalType": "string",
"description": "Name of the cohort."
}
]
}
],
"team": {
"name": "marketing"
}
}
EOF
Useful related endpoints:
GET /api/datacontracts/:idreturns the contract as JSON,GET /api/datacontracts/:id/datacontract.yamlas ODCS YAML.POST /api/datacontracts/:id/testruns a data contract test and returns the results (requires Data Contract Tests to be configured).POST /api/datacontracts/:id/generategenerates code such as SQL, dbt, JSON Schema, or Pydantic from an ODCS contract.
Description fields support Markdown and HTML formatting. See Rich Text Formatting for details.
See the Data Contracts endpoints in Swagger, and Data Contracts for the concept.
Register a data product
A typical integration flow is to PUT the data product as a CI/CD pipeline task, so the information in Entropy Data stays in sync with your source of truth.
The payload follows the Open Data Product Standard (ODPS).
team.name must reference an existing team by its id,
and the output port references the data contract registered above via contractId.
curl --request PUT https://api.entropy-data.com/api/dataproducts/customer-cohorts \
--header "x-api-key: $ENTROPY_DATA_API_KEY" \
--header "content-type: application/json" \
--data @- << EOF
{
"apiVersion": "v1.0.0",
"kind": "DataProduct",
"id": "customer-cohorts",
"name": "Customer Cohorts",
"status": "active",
"description": {
"purpose": "Customer cohorts and their properties for campaign targeting"
},
"outputPorts": [
{
"name": "snowflake-customer-cohorts-v1",
"version": "1",
"description": "Customer cohorts table in Snowflake",
"type": "snowflake",
"contractId": "customer-cohorts",
"customProperties": [
{
"property": "status",
"value": "active"
},
{
"property": "containsPii",
"value": false
},
{
"property": "server",
"value": {
"account": "lmtrwxs-xn14859",
"database": "MARKETING_DB",
"schema": "CUSTOMER_COHORTS"
}
}
]
}
],
"team": {
"name": "marketing"
}
}
EOF
GET /api/dataproducts/:id returns the data product in the same structure,
and DELETE /api/dataproducts/:id removes it (rejected with 422 while it is still used in an active access).
The deprecated Data Product Specification (DPS) format is still accepted until the end of 2026. Use ODPS for new integrations.
See the Data Products endpoints in Swagger for the full list, including starring, Git import, and Git connections, and Data Products for the concept.
Model your semantics
Model your business domain as a shared ontology of concepts and relationships, and link them to data products and data contracts.
Here, the Customer entity that the customer_cohorts schema is about is defined once, in the main namespace, so it can be reused consistently everywhere.
Concepts live in a namespace, so create the namespace first:
curl --request PUT https://api.entropy-data.com/api/semantics/experimental/namespaces/main \
--header "x-api-key: $ENTROPY_DATA_API_KEY" \
--header "content-type: application/json" \
--data @- << EOF
{
"namespace": "main",
"name": "Main",
"description": "The default namespace for the organization."
}
EOF
Then define the Customer entity as a concept in that namespace:
curl --request PUT https://api.entropy-data.com/api/semantics/experimental/namespaces/main/concepts/customer \
--header "x-api-key: $ENTROPY_DATA_API_KEY" \
--header "content-type: application/json" \
--data @- << EOF
{
"id": "customer",
"name": "Customer",
"kind": "entity",
"description": "A person or company that has purchased at least once.",
"status": "active"
}
EOF
Relationships between concepts are managed via PUT /api/semantics/experimental/namespaces/:namespace/relationships/:id,
and a whole ontology can be uploaded at once via PUT /api/semantics/experimental/namespaces/:namespace/ontology.yaml.
The Semantics API is experimental and may still change. Semantics replaces business definitions; the Definitions endpoints remain available for backwards compatibility.
See the Semantics endpoints in Swagger, and Semantics for the concept.
Automate access decisions
Access is an agreement between two teams to use a data product's output port. Access requests are usually created through the request and approval flow in the web UI. When the approval decision is managed in a third-party application, such as a ticketing or governance tool, trigger the decision through the API instead. No notification emails are sent for these calls.
curl --request POST https://api.entropy-data.com/api/access/640864de-83d4-4619-afba-ccea8037ed3a/approve \
--header "x-api-key: $ENTROPY_DATA_API_KEY"
POST /api/access/:id/approvetransitions the access fromrequestedtoapproved.POST /api/access/:id/rejecttransitions it fromrequestedtorejected.POST /api/access/:id/cancelschedules an approved access for deactivation at a specified end date, which can be now.GET /api/access/:idreturns the current state of an access resource, for example when processing an access event.
See the Access endpoints in Swagger, and Access for the concept and its lifecycle.
Report provisioning results
When an access is activated, the grant is created in your data platform by a component you run, such as a connector or a custom event handler built with the SDK.
Your component subscribes to events, acts on AccessActivatedEvent and AccessDeactivatedEvent, and reports the outcome back through the provisioning endpoints:
POST /api/access/:id/provisioning/provisioning-startedPOST /api/access/:id/provisioning/provisioning-succeededPOST /api/access/:id/provisioning/provisioning-failedPOST /api/access/:id/provisioning/deprovisioning-startedPOST /api/access/:id/provisioning/deprovisioning-succeededPOST /api/access/:id/provisioning/deprovisioning-failed
The reporting component owns the provisioning state: no transition is rejected as illegal, the latest report wins, and fields omitted from the body keep their previous value.
On success, send a reference that identifies the grant in the data platform, here the Snowflake role that grants read access to the output port:
curl --request POST https://api.entropy-data.com/api/access/640864de-83d4-4619-afba-ccea8037ed3a/provisioning/provisioning-succeeded \
--header "x-api-key: $ENTROPY_DATA_API_KEY" \
--header "content-type: application/json" \
--data @- << EOF
{
"platform": "snowflake",
"executor": "Custom Connector Snowflake V1",
"reference": "CUSTOMER_COHORTS_V1_READER",
"links": {
"Grant run log": "https://connector.example.com/runs/8412"
}
}
EOF
On failure, send the reason in diagnostics. It is shown on the access page and mailed to the providing team:
curl --request POST https://api.entropy-data.com/api/access/640864de-83d4-4619-afba-ccea8037ed3a/provisioning/provisioning-failed \
--header "x-api-key: $ENTROPY_DATA_API_KEY" \
--header "content-type: application/json" \
--data @- << EOF
{
"platform": "snowflake",
"executor": "Custom Connector Snowflake V1",
"diagnostics": "Insufficient privileges: role ENTROPY_CONNECTOR lacks MANAGE GRANTS on database MARKETING_DB."
}
EOF
Each report also emits the corresponding provisioning event. See Provisioning for the workflow, and the Access endpoints in Swagger.
Ingest assets
Assets are the raw data resources on your platform: tables, views, files, topics, pipelines, and dashboards. PUT each asset from an ingestion job that scans your platform, so the inventory stays in sync without manual updates. Once registered, an asset can be assigned to a data product or directly to an output port. Here, the ingestion job registers the Snowflake table behind the output port:
curl --request PUT https://api.entropy-data.com/api/assets/047bde7c-87d4-488a-b6d2-cef6f6f60001 \
--header "x-api-key: $ENTROPY_DATA_API_KEY" \
--header "content-type: application/json" \
--data @- << EOF
{
"id": "047bde7c-87d4-488a-b6d2-cef6f6f60001",
"info": {
"source": "snowflake",
"sourceId": "047bde7c-87d4-488a-b6d2-cef6f6f60001",
"type": "snowflake_table",
"name": "customer_cohorts",
"status": "active",
"description": "Customer cohorts and their properties."
},
"columns": [
{
"name": "customer_id",
"type": "string",
"description": "Unique customer identifier",
"required": true,
"primaryKey": true
},
{
"name": "cohort_name",
"type": "string",
"description": "Name of the cohort"
}
]
}
EOF
See the Assets endpoints in Swagger, Assets for the data model, and Ingest assets for a walkthrough.
Trigger an ingestion run
Instead of running your own ingestion job, you can use built-in integrations that ingest assets from a source platform, such as Snowflake, Databricks, BigQuery, or Microsoft Fabric, on a schedule or on demand.
Integrations are created and configured in the UI; the API identifies each one by its stable externalId.
Trigger a one-shot run, for example after a deployment:
curl --request POST https://api.entropy-data.com/api/integrations/snowflake-prod/run \
--header "x-api-key: $ENTROPY_DATA_API_KEY"
The call returns 202 Accepted, or 409 Conflict if a run is already in progress.
A run moves through the statuses RUNNING to SUCCESS, FAILED, or CANCELLED.
To wait for it to finish, poll GET /api/integrations/:externalId/runs/latest and watch the status field.
See the Integrations endpoints in Swagger.
Attach example data
Example data lets you attach sample datasets to data products, so data consumers can preview the data before requesting access.
Use an array of objects for tabular data, where each object is a row, or a single object for key-value style data such as messages.
The maximum payload size for the data field is 1 MB, and up to 30 rows are displayed.
curl --request PUT https://api.entropy-data.com/api/example-data/customer-cohorts-example \
--header "x-api-key: $ENTROPY_DATA_API_KEY" \
--header "content-type: application/json" \
--data @- << EOF
{
"id": "customer-cohorts-example",
"dataProductId": "customer-cohorts",
"outputPortId": "snowflake-customer-cohorts-v1",
"schemaName": "customer_cohorts",
"data": [
{"CUSTOMER_ID": "CUST-4821", "COHORT_NAME": "high-value"},
{"CUSTOMER_ID": "CUST-7733", "COHORT_NAME": "churn-risk"}
]
}
EOF
outputPortId scopes the entry to a specific output port, and schemaName labels the tab when an output port has multiple schemas.
See the Example Data endpoints in Swagger.
Publish test results
Publish the outcome of a data contract test run, so quality is visible next to the contract.
The Data Contract CLI publishes test results automatically when configured with an API key; use this endpoint when you run checks with your own tooling.
The server must match a server key defined in the data contract, here production.
curl --request POST https://api.entropy-data.com/api/test-results \
--header "x-api-key: $ENTROPY_DATA_API_KEY" \
--header "content-type: application/json" \
--data @- << EOF
{
"id": "466b4c17-8176-42f1-8199-59125dde5e61",
"dataContractId": "customer-cohorts",
"dataContractVersion": "1.0.0",
"server": "production",
"timestampStart": "2024-07-03T10:46:28Z",
"timestampEnd": "2024-07-03T10:46:42Z",
"result": "passed",
"checks": [
{
"type": "schema",
"name": "Check that field customer_id is present",
"model": "customer_cohorts",
"field": "customer_id",
"result": "passed",
"engine": "datacontract-cli"
}
]
}
EOF
See the Test Results endpoints in Swagger, and Test a data contract for the setup.
Run the examples as a script
To try the whole workflow against your own instance, download the usage-examples.py script. It runs every example above in order, verifies each resource with a GET request, and cleans everything up afterwards. It requires Python 3.8+ and an API key with organization scope, and has no further dependencies.
curl -O https://docs.entropy-data.com/usage-examples.py
export ENTROPY_DATA_API_KEY=your-secret-api-key
python3 usage-examples.py --prefix test-
The --prefix flag namespaces all created ids, so the run cannot collide with real resources.
The script refuses to overwrite existing resources, keeps nothing behind unless you pass --keep,
and for self-hosted installations you can point it at your instance with --host.
What's next?
- Subscribe to events to trigger automation in your data platform.
- Explore the OpenAPI Specification for all endpoints, parameters, and schemas.
- Set up CI/CD integration to run these calls from your pipelines.