Data Source Integration Guide
Connect your DMS, telemetry, parts inventory, and customer systems to Planara. Everything a dealer IT team or OEM integration partner needs to get data flowing.
Overview
Planara is an AI-powered technical assistance platform. It ingests OEM documentation (service manuals, owner's manuals, technical bulletins) and combines it with live operational data to give technicians contextual, cited answers while they work.
The documentation is the foundation. Operational data — work orders, telemetry, parts inventory, customer records — is what makes the AI responses specific to the job in front of the technician.
What Planara consumes
| Data source | What it is | How it helps |
|---|---|---|
| OEM Documentation | Service manuals, owner's manuals, wiring diagrams, TSBs | Procedures, specs, safety warnings, citations |
| Work Orders / Jobs | Job queue, complaints, fault codes, assigned tech | Job-specific diagnosis, fault code correlation |
| Telemetry | Engine readings, sensor data, historical events | "Your coolant temp is 203°F — above the 195°F threshold" |
| Parts Inventory | Part numbers, stock levels, bin locations | "Part 6AW-82560-00 is in stock, bin A3-22" |
| Customer / Equipment | Equipment identity, service history, warranty | "This engine has 487 hours. Last service was at 312 hours." |
How data flows
┌─────────────────────┐
│ Your Systems │
│ DMS / Telemetry / │
│ ERP / CRM │
└──────────┬──────────┘
│ REST / Webhook / SSE / File Import
▼
┌─────────────────────┐
│ Planara API │
│ /v1/data/{namespace}│
│ │
│ Normalizes data │
│ into canonical │
│ types, caches, │
│ enforces auth │
└──────────┬──────────┘
│
┌─────┴──────┐
▼ ▼
┌─────────┐ ┌──────────┐
│ AI │ │ Frontend │
│ Pipeline│ │ Widgets │
│ │ │ │
│ Uses │ │ Queue, │
│ context │ │ Telemetry,│
│ in RAG │ │ Parts, │
│ queries │ │ Customer │
└─────────┘ └──────────┘Every data source you connect improves the AI. The pipeline assembles a context object for each query that includes equipment identity, active fault codes, telemetry readings, parts availability, and service history. The more context available, the more specific and actionable the AI response.
Concrete impact
Without telemetry, a technician asking "is this overheating?" gets a generic answer about normal operating ranges from the manual. With telemetry connected, the AI responds: "Your coolant temperature is 203°F, which exceeds the 195°F warning threshold. This correlates with the P0217 fault code logged 7 times. The time-series data shows temperature climbing from 172°F to 203°F over 5 minutes at cruise RPM."
Data Sources — What to Expose
Each data source below documents required, recommended, and optional fields. Required fields are the minimum for Planara to display meaningful data. Recommended fields significantly improve AI response quality. Optional fields add polish.
Telemetry
Telemetry data powers the Vitals widget and gives the AI real-time awareness of equipment state.
Telemetry Fields (current readings)
Each field represents a single sensor reading with threshold metadata.
Required fields:
{
"key": "coolant_temp_f",
"label": "Coolant Temp",
"value": 203,
"unit": "°F"
}Recommended fields (enables warning/critical indicators):
{
"key": "coolant_temp_f",
"label": "Coolant Temp",
"value": 203,
"unit": "°F",
"warn_low": null,
"warn_high": 195,
"critical_low": null,
"critical_high": 210
}Full schema:
{
"key": "string — unique identifier (e.g. coolant_temp_f, oil_pressure_psi, rpm)",
"label": "string — display name",
"value": "number | null — current reading, null if sensor unavailable",
"unit": "string — display unit (°F, PSI, RPM, V, hrs)",
"warn_low": "number | null — below this value triggers warning",
"warn_high": "number | null — above this value triggers warning",
"critical_low": "number | null — below this triggers critical alert",
"critical_high": "number | null — above this triggers critical alert"
}Standard field keys Planara recognizes:
| Key | Label | Typical unit | Notes |
|---|---|---|---|
coolant_temp_f | Coolant Temp | °F | Convert from °C if needed |
oil_pressure_psi | Oil Pressure | PSI | |
rpm | RPM | RPM | |
battery_voltage | Battery | V | |
engine_hours | Engine Hours | hrs | No thresholds — informational |
fuel_pressure_psi | Fuel Pressure | PSI | |
boost_pressure_psi | Boost Pressure | PSI | Turbocharged engines |
exhaust_temp_f | Exhaust Temp | °F | |
transmission_temp_f | Trans Temp | °F |
You can send additional custom fields with any key. Planara will display them and include them in AI context.
Telemetry Events (historical incidents)
Events are timestamped incidents with time-series data for charting. They appear in the Telemetry widget's event timeline.
{
"id": "evt-1",
"timestamp": "2026-03-15T14:23:00Z",
"peak": 203,
"rpm": 4950,
"severity": "critical",
"data": [
{ "t": "0:00", "v": 172 },
{ "t": "0:30", "v": 173 },
{ "t": "1:00", "v": 174 },
{ "t": "2:00", "v": 182 },
{ "t": "3:00", "v": 191 },
{ "t": "4:00", "v": 198 },
{ "t": "5:00", "v": 203 }
]
}| Field | Required | Type | Notes |
|---|---|---|---|
id | Yes | string | Unique event identifier |
timestamp | Yes | string (ISO 8601) | When the event occurred |
peak | Yes | number | Peak value during the event |
rpm | Recommended | number | RPM at time of event |
severity | Yes | "critical" | "warning" | "info" | Determines display styling |
data | Yes | { t: string, v: number }[] | Time-series for charting. t is relative offset, v is the reading. |
Telemetry Profile (aggregate context)
If your system can provide a pre-built profile, send it as a single object. Otherwise, Planara assembles this from individual field and event data.
{
"events": [ "...array of TelemetryEvent" ],
"threshold": 195,
"unit": "°F",
"domain": [160, 210],
"ticks": [170, 185, 200],
"fields": [ "...array of TelemetryField" ]
}Update frequency
| Mode | Frequency | Use case |
|---|---|---|
| Polling | Every 30–60 seconds | Equipment in the bay, engine running |
| SSE stream | Real-time push | Live monitoring during test runs |
| Webhook | On threshold breach | Alert-driven — only fires when something changes |
| Batch | Hourly or daily | Historical data backfill |
Work Orders / Jobs
Work order data powers the job queue, complaint context, and fault code awareness.
Queue Job (list view)
This is the summary shown in the technician's job list.
Required fields:
{
"id": "WO-2026-04187",
"label": "Blue Logic",
"equipment": "F350A",
"complaint": "Intermittent overheat alarm at cruise RPM",
"priority": "high"
}Full schema:
{
"id": "string — work order ID from your DMS",
"label": "string — asset/vessel/unit name",
"sublabel": "string — asset description (e.g. 'Grady-White Canyon 376')",
"equipment": "string — primary equipment model",
"equipmentCount": "number — how many units on this asset",
"hours": "number — current equipment hours",
"complaint": "string — one-line complaint summary",
"priority": "'critical' | 'high' | 'normal' | 'low'",
"faultCode": "string | null — primary DTC/fault code",
"faultDescription": "string | null — human-readable fault description",
"partsStatus": "'staged' | 'ordered' | 'not_staged' | 'n/a'",
"assessmentReady": "boolean — true if AI assessment can run",
"bay": "string — bay/dock/lift/slot assignment",
"customer": "string — customer name",
"assignedAt": "string — ISO 8601 timestamp"
}Work Order Detail
Full work order data loaded when a technician selects a job.
{
"woNumber": "WO-2026-04187",
"status": "assigned",
"priority": "high",
"serviceWriter": "Dave Kowalski",
"assignedTech": "Mike Rezendes",
"bay": "Bay 3",
"customer": {
"name": "Robert Cahill",
"phone": "401-555-0173",
"email": "rcahill@gmail.com"
},
"asset": {
"name": "Blue Logic",
"make": "Grady-White",
"model": "Canyon 376",
"year": 2024,
"identifier": "YAMA2341K526"
},
"equipment": [
{
"id": "stbd",
"label": "Starboard",
"model": "F350A",
"serial": "6CJ-1042867",
"hours": 487.3,
"cycles": 0,
"lastServiceHours": 312,
"lastServiceDate": "2025-11-14",
"warrantyStatus": "active",
"faultCodes": [
{
"code": "P0217",
"description": "Engine Coolant Over Temperature",
"occurrenceCount": 7
}
]
}
],
"complaint": {
"description": "Intermittent overheat alarm at cruise RPM (4800-5200). No alarm at idle or WOT.",
"customerVerbatim": "It beeps at me around 30 knots but goes away if I slow down or speed up.",
"faultCodes": [
{
"code": "P0217",
"description": "Engine Coolant Over Temperature",
"occurrenceCount": 7
}
]
},
"partsOnOrder": [],
"serviceHistory": []
}Required fields for work order detail:
| Field | Required | Notes |
|---|---|---|
woNumber | Yes | Unique work order identifier |
status | Yes | "draft" | "assigned" | "in_progress" | "complete" | "invoiced" |
customer.name | Yes | |
asset.name | Recommended | Asset/vessel/unit display name |
equipment[].model | Yes | Equipment model for documentation lookup |
equipment[].serial | Recommended | For warranty and service history lookup |
equipment[].hours | Recommended | Critical for service interval context |
complaint.description | Yes | Used as the seed for AI assessment |
complaint.faultCodes | Recommended | Each with code and description |
complaint.customerVerbatim | Optional | Original customer words — helps AI understand the real symptom |
Fault Codes
Fault codes can be sent as part of the work order complaint, as part of equipment data, or via the dedicated diagnostics endpoint.
{
"code": "P0217",
"description": "Engine Coolant Over Temperature",
"occurrenceCount": 7,
"firstSeen": "2026-03-02T15:45:00Z",
"lastSeen": "2026-03-15T14:23:00Z",
"severity": "critical",
"freezeFrameData": {
"coolant_temp": "203°F",
"rpm": "4950",
"engine_hours": "486.1"
}
}Planara accepts standard OBD-II codes (P0xxx, P2xxx), manufacturer-specific codes, and proprietary fault code formats. Include the description field — Planara does not maintain a universal fault code dictionary.
Update frequency
| Trigger | Recommendation |
|---|---|
| Job creation/assignment | Push immediately via webhook |
| Status change | Push immediately |
| Parts status change | Push within 5 minutes |
| New fault code logged | Push immediately |
| Batch sync | Every 15 minutes for full queue refresh |
Parts Inventory
Parts data powers the Parts widget and lets the AI tell technicians what's available.
Part Entry (per work order)
Parts associated with a specific job.
Required fields:
{
"partNumber": "6AW-82560-00-00",
"description": "Thermoswitch",
"quantity": 1,
"status": "in_stock"
}Full schema:
{
"partNumber": "string — OEM part number",
"description": "string — part name",
"quantity": "number — quantity needed",
"status": "'in_stock' | 'ordered' | 'backordered' | 'picked' | 'n/a'",
"binLocation": "string — physical location in parts room (e.g. 'A4-17')",
"unitCost": "number — cost per unit",
"estimatedArrival": "string | null — ISO date for ordered/backordered parts"
}Parts Availability (inventory lookup)
For checking stock across inventory, not tied to a specific work order.
{
"partNumber": "6AW-82560-00-00",
"inStock": 3,
"onOrder": 0,
"binLocation": "A3-22",
"unitCost": 42.50,
"vendor": "Yamaha Marine Parts",
"leadTimeDays": null
}Substitute Parts Mapping (optional)
If your system tracks superseded or substitute part numbers, send them as an array:
{
"partNumber": "6AW-82560-00-00",
"substitutes": [
{
"partNumber": "6AW-82560-01-00",
"relationship": "supersedes",
"notes": "Updated connector type"
}
]
}Update frequency
| Trigger | Recommendation |
|---|---|
| Parts staged for a job | Push immediately |
| Inventory level change | Push within 5 minutes |
| Parts received | Push immediately |
| Full inventory sync | Daily |
Customer / Equipment
Customer and equipment data powers the Customer widget and gives the AI historical awareness.
Customer Info
{
"name": "Robert Cahill",
"phone": "401-555-0173",
"email": "rcahill@gmail.com",
"company": "Cahill Fishing Charters",
"accountNumber": "CUST-10042"
}| Field | Required | Notes |
|---|---|---|
name | Yes | |
phone | Yes | Displayed in Customer widget for tech reference |
email | Optional | |
company | Optional | |
accountNumber | Optional | Your DMS customer ID |
Equipment Identity
Equipment data is embedded in the work order equipment[] array. Key fields:
{
"id": "stbd",
"label": "Starboard",
"model": "F350A",
"serial": "6CJ-1042867",
"hours": 487.3,
"cycles": 0,
"lastServiceHours": 312,
"lastServiceDate": "2025-11-14",
"warrantyStatus": "active",
"faultCodes": []
}| Field | Required | AI impact |
|---|---|---|
model | Yes | Matches to correct OEM documentation set |
serial | Recommended | Links warranty and recall data |
hours | Recommended | Enables "next service at X hours" context |
lastServiceHours | Recommended | AI references service interval gaps |
warrantyStatus | Optional | "active" | "expired" | "unknown" | "void" |
faultCodes | Recommended | Persistent codes attached to the equipment |
Service History
[
{
"date": "2025-11-14",
"hoursAtService": 312,
"description": "300hr service — oil/filter, gear oil, spark plugs, fuel filter, anodes",
"woNumber": "WO-2025-03881",
"technician": "Mike Rezendes"
},
{
"date": "2025-04-22",
"hoursAtService": 118,
"description": "100hr service — oil/filter, gear oil inspection"
}
]| Field | Required | Notes |
|---|---|---|
date | Yes | ISO date string |
hoursAtService | Recommended | Equipment hours at time of service |
description | Yes | What was done |
woNumber | Optional | Cross-reference to historical WO |
technician | Optional | Who performed the work |
Service history is sorted newest-first. Send the last 10-20 entries. The AI uses this to identify patterns ("this is the third time this engine has had cooling system work").
Integration Methods
REST API Adapter (push to Planara)
Push data to Planara's namespaced endpoints. This is the most common integration method.
Base URL: https://your-api-domain.planara.com/v1/data/{namespace}
| Endpoint | Method | Description |
|---|---|---|
/jobs | GET | Fetch job queue |
/jobs | POST | Push a new or updated job |
/job/{id} | GET | Fetch work order detail |
/job/{id} | PUT | Update a work order |
/job/{id}/status | PATCH | Update job status only |
/telemetry/{equipment_id} | POST | Push telemetry snapshot |
/telemetry/{equipment_id}/stream | SSE | Stream live telemetry |
/parts/{wo_number} | POST | Push parts for a work order |
/parts/availability | POST | Push inventory availability |
/customer/{wo_number} | POST | Push customer info |
/diagnostics/{equipment_id} | POST | Push fault codes |
Example: Push a work order
curl -X POST https://your-api-domain.planara.com/v1/data/your-namespace/jobs \
-H "Authorization: Bearer pk_live_abc123" \
-H "Content-Type: application/json" \
-d '{
"id": "WO-2026-04187",
"label": "Blue Logic",
"sublabel": "Grady-White Canyon 376",
"equipment": "F350A",
"equipmentCount": 1,
"hours": 487.3,
"complaint": "Intermittent overheat alarm at cruise RPM",
"priority": "high",
"faultCode": "P0217",
"faultDescription": "Engine Coolant Over Temperature",
"partsStatus": "staged",
"bay": "Bay 3",
"customer": "Robert Cahill",
"assignedAt": "2026-03-18T08:42:00Z"
}'Example: Push telemetry
curl -X POST https://your-api-domain.planara.com/v1/data/your-namespace/telemetry/stbd-blue-logic \
-H "Authorization: Bearer pk_live_abc123" \
-H "Content-Type: application/json" \
-d '{
"equipmentId": "stbd-blue-logic",
"timestamp": "2026-03-18T14:30:00Z",
"fields": [
{ "key": "coolant_temp_f", "label": "Coolant Temp", "value": 185, "unit": "°F", "warn_high": 195, "critical_high": 210 },
{ "key": "oil_pressure_psi", "label": "Oil Pressure", "value": 52, "unit": "PSI", "warn_low": 25, "critical_low": 15 },
{ "key": "rpm", "label": "RPM", "value": 750, "unit": "RPM" },
{ "key": "battery_voltage", "label": "Battery", "value": 14.2, "unit": "V", "warn_low": 11.5, "warn_high": 15.0 }
],
"engineState": "idle"
}'Webhook Adapter (Planara calls you)
Register webhook endpoints and Planara pulls data on demand. Useful when your system is the source of truth and you don't want to push updates.
Configuration (set in Planara backoffice under Settings > Integrations):
{
"type": "webhook",
"provider": "custom_dms",
"endpoints": {
"jobs": "https://your-dms.com/api/planara/jobs",
"job_detail": "https://your-dms.com/api/planara/job/{id}",
"parts": "https://your-dms.com/api/planara/parts/{wo_number}",
"customer": "https://your-dms.com/api/planara/customer/{wo_number}",
"telemetry": "https://your-dms.com/api/planara/telemetry/{equipment_id}"
},
"auth": {
"type": "bearer",
"header": "Authorization"
},
"polling_interval_seconds": 60,
"timeout_ms": 5000
}Planara sends a GET request to your endpoint with the interpolated parameters. Your endpoint must return data in Planara's canonical format (the JSON schemas documented above).
Webhook request headers Planara sends:
Authorization: Bearer {your_configured_token}
X-Planara-Namespace: yamaha
X-Planara-Request-Id: req_abc123
Accept: application/jsonSSE / MQTT Streaming (real-time telemetry)
For live telemetry during engine test runs or sea trials.
SSE (Server-Sent Events):
Your system sends events to Planara's SSE ingestion endpoint, or Planara subscribes to your SSE stream.
Push mode (your system pushes to Planara):
curl -X POST https://your-api-domain.planara.com/v1/data/your-namespace/telemetry/stbd-blue-logic/stream \
-H "Authorization: Bearer pk_live_abc123" \
-H "Content-Type: text/event-stream" \
--data-binary @- << 'EOF'
data: {"fields":[{"key":"coolant_temp_f","value":185,"unit":"°F"}],"timestamp":"2026-03-18T14:30:00Z"}
data: {"fields":[{"key":"coolant_temp_f","value":187,"unit":"°F"}],"timestamp":"2026-03-18T14:30:30Z"}
data: {"fields":[{"key":"coolant_temp_f","value":192,"unit":"°F"}],"timestamp":"2026-03-18T14:31:00Z"}
EOFSubscribe mode (Planara reads your SSE stream):
Configure in backoffice:
{
"type": "telemetry_source",
"provider": "siren_marine",
"streaming": {
"protocol": "sse",
"url": "https://api.sirenmarine.com/v2/vessels/{vessel_id}/stream",
"auth": { "type": "bearer" }
}
}MQTT (for on-premises / marina network):
{
"type": "telemetry_source",
"provider": "nmea_gateway",
"streaming": {
"protocol": "mqtt",
"broker": "mqtt://192.168.1.100:1883",
"topic": "planara/{namespace}/telemetry/{equipment_id}",
"qos": 1
}
}File Import (bulk upload)
For initial data load or systems without API access.
Supported formats: JSON, CSV
Upload endpoint:
curl -X POST https://your-api-domain.planara.com/v1/data/your-namespace/import \
-H "Authorization: Bearer pk_live_abc123" \
-F "type=jobs" \
-F "file=@work_orders.json"CSV format for jobs:
id,label,sublabel,equipment,hours,complaint,priority,faultCode,faultDescription,bay,customer,assignedAt
WO-2026-04187,Blue Logic,Grady-White Canyon 376,F350A,487.3,Intermittent overheat alarm,high,P0217,Engine Coolant Over Temperature,Bay 3,Robert Cahill,2026-03-18T08:42:00Z
WO-2026-04192,Reel Therapy,Yellowfin 36,F300A,1203,Annual service — 1200hr,normal,,,Bay 5,Tom Henderson,2026-03-18T09:15:00ZCSV format for parts:
woNumber,partNumber,description,quantity,status,binLocation,unitCost
WO-2026-04187,6AW-12457-00-00,Thermostat,2,in_stock,A4-17,34.95
WO-2026-04187,6AW-12414-00-00,Gasket thermostat cover,2,in_stock,A4-18,8.75Authentication and Security
API key provisioning
Each integration gets its own API key, scoped to a namespace. Keys are created in the Planara backoffice under Settings > Integrations > API Keys.
| Key type | Prefix | Scope | Use case |
|---|---|---|---|
| Live | pk_live_ | Production data, read/write | DMS integration, telemetry push |
| Test | pk_test_ | Test endpoints only, no production data | Integration development |
Include the key in every request:
Authorization: Bearer pk_live_abc123def456Credential storage
When Planara calls your systems (webhook mode), your credentials are stored encrypted in Planara's vault. Credentials are never logged, never included in traces, and never sent to the AI pipeline.
Supported auth methods for outbound calls:
| Method | Configuration |
|---|---|
| Bearer token | { "type": "bearer", "token": "your_token" } |
| Basic auth | { "type": "basic", "username": "...", "password": "..." } |
| API key header | { "type": "api_key", "header": "X-API-Key", "value": "..." } |
| OAuth 2.0 | { "type": "oauth2", "client_id": "...", "client_secret": "...", "token_url": "..." } |
Network requirements
| Requirement | Detail |
|---|---|
| TLS | All API communication requires TLS 1.2+. No plaintext HTTP. |
| IP allowlisting | If your firewall requires it, Planara's egress IPs are listed in the backoffice under Settings > Network. |
| Webhook verification | Planara signs outbound webhook requests with HMAC-SHA256. Verify the X-Planara-Signature header. |
| Rate limits | 1000 requests/minute per API key. Telemetry streaming is unlimited. Contact us for higher limits. |
Quality Impact Matrix
This table shows what the AI can do based on which data sources are connected.
| Data available | AI can do | AI cannot do |
|---|---|---|
| Documentation only | Procedures, specs, safety warnings, citations, general diagnosis from fault code description | Job-specific advice, telemetry correlation, parts availability, service history context |
| + Work orders | Job-specific diagnosis, fault code correlation, complaint-aware assessment, customer context | Live monitoring, parts availability, service interval tracking |
| + Telemetry | "Your coolant temp is 203°F, above the 195°F threshold." Time-series correlation. Event pattern detection. | Parts availability, substitute part lookup |
| + Parts | "Part 6AW-82560-00 is in stock, bin A3-22." Proactive parts lists for procedures. Backorder alerts. | Nothing significant — this is near full capability |
| + Service history | "This is the third cooling system repair in 6 months — consider a systematic inspection." Warranty-aware recommendations. Interval tracking. | — |
| All sources connected | Full contextual assistance. Every AI response grounded in live equipment state, job context, parts reality, and service history. | — |
Each additional data source is additive. There is no penalty for partial integration — Planara gracefully degrades. A deployment with only documentation and work orders is still valuable. Telemetry and parts make it significantly better.
Testing Your Integration
Test endpoints
Every data endpoint has a test mode. Use your pk_test_ key to hit the same endpoints without affecting production data.
# Push test data
curl -X POST https://your-api-domain.planara.com/v1/data/your-namespace/jobs \
-H "Authorization: Bearer pk_test_abc123" \
-H "Content-Type: application/json" \
-d '{ "id": "TEST-001", "label": "Test Vessel", "equipment": "F350A", "complaint": "Test complaint", "priority": "normal" }'
# Verify it arrived
curl https://your-api-domain.planara.com/v1/data/your-namespace/jobs \
-H "Authorization: Bearer pk_test_abc123"Test data is isolated from production and automatically purged after 24 hours.
Validation
Planara validates every inbound payload. Invalid requests return structured errors:
{
"error": "validation_error",
"message": "Missing required field: complaint",
"details": [
{
"field": "complaint",
"rule": "required",
"message": "The 'complaint' field is required for queue jobs"
}
],
"request_id": "req_abc123"
}Common validation errors:
| Error | Cause | Fix |
|---|---|---|
missing_required_field | A required field is null or absent | Add the field to your payload |
invalid_enum_value | Field value not in allowed set (e.g., priority: "urgent") | Use one of: critical, high, normal, low |
invalid_date_format | Date not in ISO 8601 | Use YYYY-MM-DD or full ISO 8601 with timezone |
duplicate_id | A record with this ID already exists | Use PUT to update, or generate a unique ID |
namespace_mismatch | API key namespace doesn't match URL namespace | Check your API key is for the correct namespace |
Backoffice monitoring
Once connected, monitor your integration health in the Planara backoffice under Monitoring > Integrations:
- Last sync timestamp for each data source
- Error rate over the last 24 hours
- Payload samples — see the last 10 successful and failed payloads
- Latency — p50/p95 response times for webhook calls
- Data freshness — how old is the newest record for each source
Integration Examples
Lightspeed EVO (DMS)
Lightspeed EVO is a common dealer management system in the marine industry. This example shows the webhook adapter configuration.
Backoffice configuration:
{
"name": "Lightspeed EVO",
"type": "dms",
"provider": "lightspeed",
"credentials": {
"type": "oauth2",
"client_id": "planara_integration",
"client_secret": "••••••••",
"token_url": "https://api.lightspeedevo.com/oauth/token",
"scope": "work_orders.read parts.read customers.read"
},
"endpoints": {
"jobs": "/api/v2/work-orders?status=open&assigned=true",
"job_detail": "/api/v2/work-orders/{id}",
"parts": "/api/v2/work-orders/{wo_number}/parts",
"customer": "/api/v2/customers/{customer_id}"
},
"field_mapping": {
"jobs": {
"id": "$.work_order_number",
"label": "$.vessel.name",
"sublabel": "$.vessel.make + ' ' + $.vessel.model",
"equipment": "$.engines[0].model",
"hours": "$.engines[0].hours",
"complaint": "$.complaint_summary",
"priority": "$.priority_level",
"faultCode": "$.dtc_codes[0].code",
"customer": "$.customer.full_name",
"bay": "$.bay_assignment"
}
},
"polling_interval_seconds": 30
}What Planara does:
- Polls Lightspeed EVO every 30 seconds for open work orders
- Maps Lightspeed's field names to Planara's canonical types using
field_mapping - Caches responses to avoid hammering the DMS API
- Serves normalized data to both the frontend and AI pipeline
Siren Marine (telemetry)
Siren Marine provides real-time vessel monitoring via cellular-connected sensors.
Backoffice configuration:
{
"name": "Siren Marine",
"type": "telemetry_source",
"provider": "siren_marine",
"credentials": {
"type": "api_key",
"header": "X-Siren-API-Key",
"value": "••••••••"
},
"streaming": {
"protocol": "sse",
"url": "https://api.sirenmarine.com/v2/vessels/{vessel_id}/stream"
},
"field_mapping": {
"siren_engine_temp": { "key": "coolant_temp_f", "label": "Coolant Temp", "unit": "°F" },
"siren_oil_psi": { "key": "oil_pressure_psi", "label": "Oil Pressure", "unit": "PSI" },
"siren_rpm": { "key": "rpm", "label": "RPM", "unit": "RPM" },
"siren_battery": { "key": "battery_voltage", "label": "Battery", "unit": "V" },
"siren_hours": { "key": "engine_hours", "label": "Engine Hours", "unit": "hrs" }
},
"thresholds": {
"coolant_temp_f": { "warn_high": 195, "critical_high": 210 },
"oil_pressure_psi": { "warn_low": 25, "critical_low": 15 },
"battery_voltage": { "warn_low": 11.5, "warn_high": 15.0, "critical_low": 10.5, "critical_high": 16.0 }
}
}What Planara does:
- Subscribes to Siren Marine's SSE stream for each active vessel
- Maps Siren's field names to Planara's canonical telemetry fields
- Applies threshold configuration (since Siren doesn't send thresholds)
- Streams normalized readings to the Telemetry widget in real time
- Logs events when thresholds are breached (for the event timeline)
- Includes current readings in every AI query context
Custom DMS Webhook
For in-house or niche DMS systems, implement webhook endpoints that return Planara's canonical format directly.
Your system exposes:
GET https://your-dms.com/api/planara/jobs
GET https://your-dms.com/api/planara/job/{id}
GET https://your-dms.com/api/planara/parts/{wo_number}
GET https://your-dms.com/api/planara/customer/{wo_number}Example: /api/planara/jobs response
[
{
"id": "WO-2026-04187",
"label": "Blue Logic",
"sublabel": "Grady-White Canyon 376",
"equipment": "F350A",
"equipmentCount": 1,
"hours": 487.3,
"complaint": "Intermittent overheat alarm at cruise RPM",
"priority": "high",
"faultCode": "P0217",
"faultDescription": "Engine Coolant Over Temperature",
"partsStatus": "staged",
"assessmentReady": true,
"bay": "Bay 3",
"customer": "Robert Cahill",
"assignedAt": "2026-03-18T08:42:00Z"
}
]Example: /api/planara/parts/WO-2026-04187 response
[
{
"partNumber": "6AW-12457-00-00",
"description": "Thermostat",
"quantity": 2,
"status": "in_stock",
"binLocation": "A4-17",
"unitCost": 34.95
},
{
"partNumber": "6AW-12414-00-00",
"description": "Gasket, thermostat cover",
"quantity": 2,
"status": "in_stock",
"binLocation": "A4-18",
"unitCost": 8.75
}
]Backoffice configuration:
{
"name": "Custom DMS",
"type": "dms",
"provider": "custom",
"credentials": {
"type": "bearer",
"token": "••••••••"
},
"endpoints": {
"jobs": "https://your-dms.com/api/planara/jobs",
"job_detail": "https://your-dms.com/api/planara/job/{id}",
"parts": "https://your-dms.com/api/planara/parts/{wo_number}",
"customer": "https://your-dms.com/api/planara/customer/{wo_number}"
},
"polling_interval_seconds": 60
}When your endpoints return data in Planara's canonical format, no field mapping is needed. This is the simplest integration path.
Simulated DMS for Development and Demos
Planara ships with a fully simulated DMS (Dealer Management System) that mirrors the data shapes and behaviors of a real integration. This allows development, demos, and testing without requiring a live DMS connection.
The simulated DMS includes:
| Data | Scope | Details |
|---|---|---|
| Work orders | 10 jobs | Mixed priorities (critical, high, normal, low), statuses, fault codes, parts staging, and service history |
| Parts catalog | 20 parts | Search endpoint, availability checking, bin locations, costs, and substitute part mappings |
| Technical Service Bulletins | 7 TSBs | Model-specific and symptom-matched bulletins surfaced during diagnosis |
| Service history | Per-equipment | Historical service records with recurring fault detection |
| Streaming telemetry | Real-time SSE | Random-walk simulation with configurable threshold zones (normal, warning, critical) |
Adapter pattern
All simulated data is served through the same adapter pattern used for production integrations: /v1/data/{namespace}/*. The simulated adapter and a real DMS adapter implement the same interface. Swapping from simulated to real DMS data requires configuring a new adapter — no frontend or pipeline changes needed.
This architecture means you can:
- Run demos with realistic data immediately after deployment
- Develop and test frontend features against stable, predictable data
- Switch to a real DMS connection per-tenant when ready, with zero code changes
Next Steps
- Get your API keys — Contact your Planara account manager or generate keys in the backoffice under Settings > Integrations
- Start with work orders — This gives the biggest immediate quality improvement
- Add telemetry — Connect your monitoring system for live equipment awareness
- Test end-to-end — Use the test endpoints to verify data flows through to the AI
- Monitor in backoffice — Watch the integration health dashboard for errors or stale data
Questions? Reach us at integrations@planara.com or through the support channel in the backoffice.