REST API

Complete reference for Conduit's REST API - authentication, endpoints, and response formats.

REST API Reference

Conduit provides a comprehensive REST API for programmatic access to queries, tags, adapters, and system management.

Base URL

https://your-conduit-instance.com/api/v1

Authentication

Bearer Token (JWT)

curl -X POST https://conduit.example.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "user@example.com", "password": "password"}'

Response:

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIs...",
  "expiresIn": 86400
}

Use the token in subsequent requests:

curl https://conduit.example.com/api/v1/tags \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."

API Key

For service-to-service communication:

curl https://conduit.example.com/api/v1/tags \
  -H "X-API-Key: your-api-key"

Queries

Execute NQE Query

POST /api/v1/query/nqe

Request:

{
  "query": "Show temperature for Tank1 over the last hour",
  "options": {
    "timeout": 30000,
    "format": "json"
  }
}

Response:

{
  "id": "q_abc123",
  "status": "completed",
  "query": "Show temperature for Tank1 over the last hour",
  "nqe": "Show value by timestamp during last 1 hour, where tag is Tank1_Temperature",
  "metadata": {
    "executionTime": 145,
    "rowCount": 60,
    "sources": ["ignition-plant-1"]
  },
  "columns": [
    {"name": "timestamp", "type": "datetime"},
    {"name": "value", "type": "number"}
  ],
  "data": [
    ["2026-01-21T10:00:00Z", 145.3],
    ["2026-01-21T10:01:00Z", 145.7]
  ]
}

Execute Structured Query

POST /api/v1/query/nqe

Request:

{
  "nqe": "Show value by timestamp during last 1 hour, where tag is Tank1_Temperature"
}

Get Query Status

GET /api/v1/query/{queryId}

Cancel Query

DELETE /api/v1/query/{queryId}

Tags

List Tags

GET /api/v1/tags

Query Parameters: | Parameter | Type | Description | |-----------|------|-------------| | search | string | Search term for tag names | | source | string | Filter by source adapter | | section | string | Filter by UNS section | | page | integer | Page number (default: 1) | | limit | integer | Results per page (default: 100) |

Response:

{
  "tags": [
    {
      "id": "tag_123",
      "name": "Tank1_Temperature",
      "description": "Tank 1 Process Temperature",
      "unit": "°F",
      "dataType": "float64",
      "source": "ignition-plant-1",
      "path": "Plant/Area1/Tank1/Temperature",
      "metadata": {
        "lastValue": 145.3,
        "lastTimestamp": "2026-01-21T10:30:00Z",
        "quality": "good"
      }
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 100,
    "total": 1523,
    "pages": 16
  }
}

Get Tag Details

GET /api/v1/tags/{tagId}

Update Tag Metadata

PATCH /api/v1/tags/{tagId}

Request:

{
  "description": "Updated description",
  "unit": "°C",
  "metadata": {
    "owner": "operations",
    "criticality": "high"
  }
}

Search Tags (Semantic)

POST /api/v1/tags/search

Request:

{
  "query": "cooling water temperature",
  "limit": 10,
  "threshold": 0.7
}

Response:

{
  "results": [
    {
      "tag": { /* tag object */ },
      "score": 0.92,
      "matchType": "semantic"
    }
  ]
}

Adapters

List Adapters

GET /api/v1/adapters

Response:

{
  "adapters": [
    {
      "id": "adapter_123",
      "name": "ignition-plant-1",
      "type": "ignition",
      "status": "connected",
      "tagCount": 1523,
      "lastSeen": "2026-01-21T10:30:00Z",
      "health": {
        "status": "healthy",
        "latency": 45,
        "errors": 0
      }
    }
  ]
}

Get Adapter Details

GET /api/v1/adapters/{adapterId}

Trigger Discovery

POST /api/v1/adapters/{adapterId}/discover

Get Adapter Metrics

GET /api/v1/adapters/{adapterId}/metrics

Users & Permissions

List Users

GET /api/v1/users

Create User

POST /api/v1/users

Request:

{
  "email": "user@example.com",
  "name": "Jane Doe",
  "role": "operator",
  "password": "secure-password"
}

Update User

PATCH /api/v1/users/{userId}

Delete User

DELETE /api/v1/users/{userId}

List Roles

GET /api/v1/roles

System

Health Check

GET /api/v1/health

Response:

{
  "status": "healthy",
  "version": "1.5.0",
  "uptime": 86400,
  "components": {
    "database": "healthy",
    "mqtt": "healthy",
    "cache": "healthy"
  }
}

System Metrics

GET /api/v1/system/metrics

Audit Log

GET /api/v1/system/audit

Query Parameters: | Parameter | Type | Description | |-----------|------|-------------| | startDate | datetime | Filter from date | | endDate | datetime | Filter to date | | user | string | Filter by user | | action | string | Filter by action type |

Error Responses

All errors follow a consistent format:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid query syntax",
    "details": {
      "field": "query",
      "reason": "Unexpected token at position 15"
    },
    "requestId": "req_xyz789"
  }
}

Error Codes

| Code | HTTP Status | Description | |------|-------------|-------------| | VALIDATION_ERROR | 400 | Invalid request data | | AUTHENTICATION_ERROR | 401 | Invalid or missing credentials | | AUTHORIZATION_ERROR | 403 | Insufficient permissions | | NOT_FOUND | 404 | Resource not found | | CONFLICT | 409 | Resource conflict | | RATE_LIMITED | 429 | Too many requests | | INTERNAL_ERROR | 500 | Server error | | SERVICE_UNAVAILABLE | 503 | Service temporarily unavailable |

Rate Limiting

API requests are rate-limited:

| Tier | Requests/Minute | Burst | |------|-----------------|-------| | Free | 60 | 10 | | Professional | 1000 | 100 | | Enterprise | Unlimited | - |

Rate limit headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1642780800

Pagination

List endpoints support pagination:

GET /api/v1/tags?page=2&limit=50

Response includes pagination metadata:

{
  "data": [...],
  "pagination": {
    "page": 2,
    "limit": 50,
    "total": 1523,
    "pages": 31,
    "hasNext": true,
    "hasPrev": true
  }
}

Webhooks

Register Webhook

POST /api/v1/webhooks

Request:

{
  "url": "https://your-app.com/webhook",
  "events": ["query.completed", "adapter.status"],
  "secret": "webhook-secret"
}

Webhook Events

| Event | Description | |-------|-------------| | query.completed | Query finished execution | | query.failed | Query execution failed | | adapter.connected | Adapter connected | | adapter.disconnected | Adapter disconnected | | tag.discovered | New tag discovered | | alert.triggered | Alert condition met |

SDKs

Official SDKs available:

  • Python: pip install conduit-sdk
  • JavaScript/TypeScript: npm install @conduit/sdk
  • Go: go get github.com/conduit-io/conduit-go

Python Example

from conduit import ConduitClient

client = ConduitClient(
    base_url="https://conduit.example.com",
    api_key="your-api-key"
)

# Execute NQE query
result = client.query.nqe("Show temperature for Tank1 over the last hour")

for row in result.data:
    print(f"{row.timestamp}: {row.value}")

JavaScript Example

import { ConduitClient } from '@conduit/sdk';

const client = new ConduitClient({
  baseUrl: 'https://conduit.example.com',
  apiKey: 'your-api-key'
});

const result = await client.query.nqe(
  'Show temperature for Tank1 over the last hour'
);

result.data.forEach(row => {
  console.log(`${row.timestamp}: ${row.value}`);
});

Next Steps