Your First Asset via API
A quickstart for creating your first asset programmatically using the Beacon Tower REST API. This guide covers the full workflow: authentication, model creation, asset creation, provider client provisioning, and binding.
Prerequisites
Before you begin, ensure you have:
- A Beacon Tower account with appropriate privileges (at minimum:
asset_managementandmodel_management) - Access to the API base URL for your Beacon Tower instance (e.g.,
https://api.beacontower.ai) - An HTTP client such as
curl, Postman, or similar - A configured provider (e.g., an IoT Hub provider) — providers are typically set up by your platform operations team
Step 1: Authenticate
Obtain a JWT access token using the Resource Owner Password Credentials (ROPC) flow:
curl -X POST https://api.beacontower.ai/auth/ropc \
-H "Content-Type: application/json" \
-d '{
"username": "user@example.com",
"password": "your-password"
}'
Response:
{
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Store the access token for convenience:
export TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
Alternative: API Key Authentication
If you have an API key, use the X-API-Key header instead:
export API_KEY="your-api-key"
For detailed information about authentication methods, see the Authentication guide.
Step 2: Create a Model
Assets are instances of models defined using DTDL. Before creating an asset, you must create and publish a model.
Create a Model Draft
curl -X POST https://api.beacontower.ai/models/drafts \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"@id": "dtmi:mycompany:TemperatureSensor;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"displayName": "Temperature Sensor",
"contents": [
{
"@type": ["Telemetry", "Temperature"],
"name": "temperature",
"displayName": "Temperature",
"schema": "double",
"unit": "degreeCelsius"
}
]
}'
Save the draft ID from the response:
export MODEL_DRAFT_ID="<id-from-response>"
Promote the Model
Draft models are not usable until promoted:
curl -X POST https://api.beacontower.ai/models/drafts/$MODEL_DRAFT_ID/promote \
-H "Authorization: Bearer $TOKEN"
The model is now published and ready for use.
Step 3: Create the Asset
With the model published, create an asset instance:
curl -X POST https://api.beacontower.ai/assets \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "temp-sensor-001",
"modelId": "dtmi:mycompany:TemperatureSensor;1",
"displayName": "Temperature Sensor 001",
"organizationId": "your-org-id"
}'
Note:
organizationIdis required. This determines which organization owns the asset and controls access permissions.
The asset exists but is not yet connected to any data source. To receive telemetry, you need to bind it — either to a provider client (for external devices) or to another asset (for asset-to-asset data routing).
Binding: Two Approaches
Beacon Tower supports two binding approaches depending on where the data comes from:
| Approach | When to Use | Key Concept |
|---|---|---|
| Provider Client + Autobind | Connecting to an external device (IoT Hub, import provider, etc.) | Create a provider client, provision it on the provider infrastructure, then autobind |
| Binding Description | Routing data from one asset to another | Use a binding description to define how signals map between asset models |
This quickstart covers the provider client approach since it's the most common for connecting physical devices. See Binding with Binding Descriptions at the end for the asset-to-asset flow.
Step 4: Create a Provider Client
A provider client represents your device's identity on the provider infrastructure. You need the provider ID for your target provider (ask your administrator).
export PROVIDER_ID="your-iot-hub-provider-id"
curl -X POST https://api.beacontower.ai/providers/$PROVIDER_ID/clients \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "device1",
"displayName": "Temperature Device 1",
"organizationId": "your-org-id",
"enabled": true
}'
The id must be unique within the provider. This becomes the device identity used for authentication and message routing.
Step 5: Provision the Provider Client
Provisioning registers the provider client on the provider's infrastructure (e.g., creates the device on IoT Hub). The options object depends on your provider type.
IoT Hub Device (minimal)
curl -X POST https://api.beacontower.ai/providers/$PROVIDER_ID/clients/device1/provision \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"options": {
"hub": "your-iot-hub-name"
}
}'
IoT Hub Device (with authentication and desired properties)
curl -X POST https://api.beacontower.ai/providers/$PROVIDER_ID/clients/device1/provision \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"options": {
"hub": "your-iot-hub-name",
"isEdge": false,
"deviceEnabled": true,
"authenticationType": "sas",
"IoTDeviceProvisioningOptions": {
"DesiredProperties": {
"UpdateInterval": 10
}
}
}
}'
Import Provider (for file/API-based data)
curl -X POST https://api.beacontower.ai/providers/$PROVIDER_ID/clients/device1/provision \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"options": {
"Signals": [
{ "Id": "temperature" },
{ "Id": "humidity" }
]
}
}'
If your provider has templates configured, you can reference one with "templateId": "template-uuid" to apply default provisioning settings.
Step 6: Bind the Asset
Now bind the asset to the provisioned provider client using autobind. The autobind function automatically creates content bindings that map the provider client's signals to the asset's telemetry definitions.
curl -X POST https://api.beacontower.ai/assets/temp-sensor-001/bind \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"autobindRemoteInstanceIds": [
"'$PROVIDER_ID'::device1"
]
}'
The autobindRemoteInstanceIds format is {providerId}::{clientId}. Autobind generates a default binding description if one doesn't exist, mapping signals from the provider client to matching telemetry definitions in the asset's model.
The asset is now fully connected. When the device sends telemetry through the provider, the data flows into the asset.
Step 7: Query Telemetry
Once your device starts sending data, query it using the timeseries endpoints.
Get Latest Values
curl -X POST https://api.beacontower.ai/timeseries/get/last \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"assetId": "temp-sensor-001",
"componentId": null,
"timeseries": null
}
]
}'
Get Historical Data
curl -X POST https://api.beacontower.ai/timeseries/get \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"assetId": "temp-sensor-001",
"timeseriesName": ["temperature"],
"searchSpanFrom": "2024-01-15T00:00:00Z",
"searchSpanTo": "2024-01-15T23:59:59Z",
"aggregationType": "avg",
"aggregationInterval": "PT5M"
}'
See Telemetry and Timeseries for details on aggregation types and intervals.
Summary: Provider Client Flow
The complete sequence for connecting an asset to an external device:
1. Create Model Draft POST /models/drafts
2. Promote Model POST /models/drafts/{id}/promote
3. Create Asset POST /assets
4. Create Provider Client POST /providers/{providerId}/clients
5. Provision Client POST /providers/{providerId}/clients/{clientId}/provision
6. Bind Asset POST /assets/{assetId}/bind (autobindRemoteInstanceIds)
Binding with Binding Descriptions
When routing data from one asset to another (instead of from a provider client), you use binding descriptions. A binding description defines how signals from a source asset model map to a target asset model.
When to Use
- Aggregating data from multiple assets into a summary asset
- Routing processed data from one asset to another
- Creating hierarchical data flows between asset models
Flow Overview
1. Create both assets (source and target)
2. Get or generate a binding description for the target model
3. Bind the target asset using the binding description + source asset ID
Step 1: Get Binding Descriptions for a Model
Check if a binding description already exists for your target model:
curl -X GET https://api.beacontower.ai/bindings/model/$TARGET_MODEL_ID \
-H "Authorization: Bearer $TOKEN"
This returns binding descriptions that define which source models are compatible (sources array) and how signals map between them.
Step 2: Generate a Binding Description (if needed)
If no existing binding description fits, generate one:
curl -X POST https://api.beacontower.ai/bindings/generate/$TARGET_MODEL_ID/$SOURCE_MODEL_ID \
-H "Authorization: Bearer $TOKEN"
Then save the generated binding description:
curl -X POST https://api.beacontower.ai/bindings \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '<generated-binding-description>'
Step 3: Bind Using the Binding Description
curl -X POST https://api.beacontower.ai/assets/$TARGET_ASSET_ID/bind \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"bindingDescriptions": [
{
"bindingDescriptionId": "btbi:dtmi:myModel;1:myBinding;1",
"instances": [
{
"instanceName": "Source Sensor",
"instanceId": "source-asset-id"
}
]
}
]
}'
The instances array maps source assets to the binding description's source slots. The system creates content bindings that route telemetry from the source asset into the target asset.
Next Steps
- API Reference — Explore all available endpoints and schemas
- Models and DTDL — Create complex models with components and semantic types
- Assets and Bindings — Deep dive into the binding system
- Alarms and Notifications — Set up automated alerting
- Dashboards — Create visual monitoring dashboards
For step-by-step guidance using the web interface, see Your First Asset via Web UI.