Skip to content

StaRT Mobile API - Complete Workflow Guide

For Mobile Developers (Jay)

This guide documents the complete API workflow for the StaRT mobile app for the January 8, 2025 beta test with the fake Bayeux Tapestry.

All examples use the v0.3.0 artwork-centric model with real API endpoints.

Base URL (Development): https://api.dev.smach.scienceOpenAPI Documentation: https://api.dev.smach.science/swagger-ui.html

Overview

The StaRT mobile app manages the complete monitoring lifecycle for artwork transport:

Setup → Start → Monitoring → Stop → Upload → Analysis
  📦      🚚        📍          🏁       📊        ✅

Monitoring Lifecycle:

  • Setup (Phase 1): Create monitoring → pending status
  • Start (Phase 2): Begin recording → in_progress status
  • Monitoring (Phase 3): Push events (alerts, positions)
  • Stop (Phase 4): End recording → ended status
  • Upload (Phase 5): Upload datalogger data → uploaded status (v1.0.0)
  • Analysis (Phase 6): Expert analysis → completed status (v1.0.0)

Authentication

Get JWT Token from Keycloak

Endpoint: https://id.smach.science/realms/smach/protocol/openid-connect/token

Client ID: start (StaRT mobile app)

Organization Scopes

StaRT uses OAuth2 scopes to control organization information in JWT tokens:

  • organization: User selects one organization at login (Keycloak displays selector if multi-org)
  • organization:*: Token contains all user organizations (no login selector)

For StaRT mobile, organization scope is recommended (explicit organization selection).

⚠️ Important:

  • You cannot use both scopes simultaneously (choose one)
  • Without a scope, no organization information in token
  • With organization scope, user can only access resources from the selected organization (even if they belong to multiple orgs)

Request with organization scope (Recommended for StaRT):

bash
curl -X POST "https://id.smach.science/realms/smach/protocol/openid-connect/token" \
  -d "client_id=start" \
  -d "username=admin@bayeux.test" \
  -d "password=PASSWORD" \
  -d "grant_type=password" \
  -d "scope=openid organization"

Response:

json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI...",
  "expires_in": 300,
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI...",
  "token_type": "Bearer",
  "scope": "openid organization"
}

Decoded JWT Token (with organization scope):

json
{
  "sub": "52673b28-ee1f-4d34-bb70-85137d4de6bd",
  "email": "admin@bayeux.test",
  "organization": {
    "bayeux": {
      "name": ["Bayeux Museum"]
    }
  },
  "realm_access": {
    "roles": ["administrator"]
  }
}

Alternative: Request with organization:* scope (All Organizations):

bash
curl -X POST "https://id.smach.science/realms/smach/protocol/openid-connect/token" \
  -d "client_id=start" \
  -d "username=admin@bayeux.test" \
  -d "password=PASSWORD" \
  -d "grant_type=password" \
  -d "scope=openid organization:*"

Decoded JWT Token (with organization:* scope):

json
{
  "sub": "52673b28-ee1f-4d34-bb70-85137d4de6bd",
  "email": "admin@bayeux.test",
  "organizations": {
    "bayeux": {
      "name": ["Bayeux Museum"]
    }
  },
  "realm_access": {
    "roles": ["administrator"]
  }
}

Scope Differences

ScopeLogin UXToken ClaimUse Case
organizationSelector at login (if multi-org)"organization": {"bayeux": {...}}Mobile apps - explicit org selection
organization:*No selector"organizations": {"bayeux": {...}}Web apps - dynamic org switching

See Organization Management for complete documentation.

Use token in all API requests:

bash
export TOKEN="eyJhbGciOiJSUzI1NiIsInR5cCI..."

Organization Header Required

All API requests (except authentication) must include:

bash
-H "X-Organization: bayeux"

For single-organization users, this header is optional (auto-resolved from JWT). For super-admins and multi-org users, this header is mandatory.


Phase 0: Authentication & Organization Selection

0.1 Get User's Organizations (v1.0.0 - multi-org support)

For super-admin users who can access multiple organizations:

bash
curl -X GET "https://api.dev.smach.science/me/organizations" \
  -H "Authorization: Bearer $TOKEN"

Response:

json
["bayeux", "louvre", "smach"]

For v0.3.0

In the current beta, focus on single organization users (admin@bayeux.test). Multi-organization selection will be needed for super.admin@smach.science in v1.0.0.


Phase 1: Setup - Create Monitoring

1.1 List Artworks Ready for Setup

Get artworks with status ready (no active monitoring):

bash
curl -X GET "https://api.dev.smach.science/artworks?status=ready" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux"

Response:

json
[
  {
    "id": "674ebf66cf6f5c456e1e27a8",
    "organization": "bayeux",
    "tags": ["Medieval Art", "Tapestry", "11th Century", "Norman Conquest"],
    "reference": "bayeux-tapestry-replica",
    "name": "Bayeux Tapestry (Test Replica)",
    "status": "ready",
    "inclosure": "INC001",
    "crate": "CRT001",
    "config": {
      "sensors": {
        "temperature": {
          "interval": 300,
          "min": 18,
          "max": 22
        },
        "humidity": {
          "interval": 300,
          "min": 45,
          "max": 55
        },
        "accelerometer": {
          "range": "±4g",
          "xMin": -5,
          "xMax": 5,
          "yMin": -5,
          "yMax": 5,
          "zMin": -5,
          "zMax": 5
        }
      },
      "logger": {
        "battery": 15,
        "storage": 100,
        "frequency": 12
      }
    },
    "checklist": [
      {
        "title": "Verify environmental seals",
        "description": "Check all seals are intact"
      },
      {
        "title": "Activate dataloggers",
        "description": "Ensure all loggers are powered"
      },
      {
        "title": "Test sensor connectivity",
        "description": "Verify sensors are reporting"
      },
      {
        "title": "Document initial conditions",
        "description": "Record temp/humidity before packaging"
      }
    ]
  }
]

1.2 Get Artwork Details

bash
curl -X GET "https://api.dev.smach.science/artworks/674ebf66cf6f5c456e1e27a8" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux"

1.3 Get Available Inventory Items

List available loggers:

bash
curl -X GET "https://api.dev.smach.science/inventories/loggers" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux"

Response:

json
[
  {
    "id": "...",
    "imei": "IMEI-LOGGER-001",
    "organization": "bayeux",
    "name": "Datalogger 001",
    "model": "AES Techno v1.0.0",
    "currentMonitoring": null
  },
  {
    "id": "...",
    "imei": "IMEI-LOGGER-002",
    "organization": "bayeux",
    "name": "Datalogger 002",
    "model": "AES Techno v1.1.2",
    "currentMonitoring": null
  }
]

List available sensors:

bash
curl -X GET "https://api.dev.smach.science/inventories/sensors" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux"

Response:

json
[
  {
    "id": "...",
    "imei": "IMEI-SENSOR-001",
    "organization": "bayeux",
    "sensorTypes": ["Temperature", "Humidity", "Accelerometer"],
    "name": "3-sensor probe (T+H+A)",
    "model": "HDC3021 + IIS3DWB",
    "currentMonitoring": null
  }
]

1.4 Create Monitoring (Setup)

Pre-Setup Tasks in App

Before calling this endpoint:

  1. ✅ User completes checklist items in UI
  2. ✅ App auto-detects dataloggers via Bluetooth
  3. ✅ App displays detected Logger+Sensor pairs
  4. ✅ (Optional) User adjusts configuration thresholds
  5. ✅ Get current GPS coordinates

Endpoint: POST /artworks/{artworkId}/monitorings

Request Body:

json
{
  "organization": "bayeux",
  "artwork": "674ebf66cf6f5c456e1e27a8",
  "type": "transport",
  "status": "pending",
  "dataloggers": [
    {
      "logger": "IMEI-LOGGER-001",
      "sensor": "IMEI-SENSOR-001",
      "note": "Top right",
      "position": {
        "latitude": 3.23,
        "longitude": 2.12
      }
    },
    {
      "logger": "IMEI-LOGGER-002",
      "sensor": "IMEI-SENSOR-002",
      "note": "Center",
      "position": {
        "latitude": 0.0,
        "longitude": 0.0
      }
    },
    {
      "logger": "IMEI-LOGGER-003",
      "sensor": "IMEI-SENSOR-003",
      "note": "Bottom left",
      "position": {
        "latitude": -3.23,
        "longitude": -2.12
      }
    }
  ],
  "config": {
    "sensors": {
      "temperature": {
        "interval": 300,
        "min": 18,
        "max": 22
      },
      "humidity": {
        "interval": 300,
        "min": 45,
        "max": 55
      },
      "accelerometer": {
        "range": "±4g",
        "xMin": -5,
        "xMax": 5,
        "yMin": -5,
        "yMax": 5,
        "zMin": -5,
        "zMax": 5
      }
    },
    "logger": {
      "battery": 15,
      "storage": 100,
      "frequency": 12
    }
  }
}

cURL Example:

bash
curl -X POST "https://api.dev.smach.science/artworks/674ebf66cf6f5c456e1e27a8/monitorings" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux" \
  -H "Content-Type: application/json" \
  -d '{
    "organization": "bayeux",
    "artwork": "674ebf66cf6f5c456e1e27a8",
    "type": "transport",
    "status": "pending",
    "dataloggers": [
      {
        "logger": "IMEI-LOGGER-001",
        "sensor": "IMEI-SENSOR-001",
        "note": "Top right",
        "position": {"latitude": 3.23, "longitude": 2.12}
      }
    ],
    "config": {...}
  }'

Response:

json
{
  "id": "674ec123cf6f5c456e1e27b9",
  "organization": "bayeux",
  "artwork": "674ebf66cf6f5c456e1e27a8",
  "type": "transport",
  "status": "pending",
  "dataloggers": [
    {
      "logger": "IMEI-LOGGER-001",
      "sensor": "IMEI-SENSOR-001",
      "note": "Top right",
      "position": {"latitude": 3.23, "longitude": 2.12}
    }
  ],
  "config": {...},
  "created": "2025-01-08T08:00:00Z",
  "updated": "2025-01-08T08:00:00Z"
}

What happens:

  • ✅ Monitoring created with pending status
  • ✅ Artwork status updated: readystandby
  • ✅ Dataloggers marked as IN_USE in inventory
  • ✅ Configuration copied from artwork.baseConfig
  • StaRT stores monitoring.id in session for next steps

Phase 2: Start - Begin Recording

When to Start

The START event should be triggered when:

  • ✅ All checklist items completed
  • ✅ Dataloggers installed and configured via Bluetooth
  • ✅ Carrier is ready to take charge of the artwork

2.1 Start Recording - POST Start Event

Endpoint: POST /artworks/{artworkId}/monitorings/events

Request Body:

json
{
  "type": "start",
  "severity": "info",
  "date": "2025-01-08T10:00:00Z",
  "location": {
    "latitude": 49.276,
    "longitude": -0.702
  },
  "sourceType": "monitoring",
  "source": "674ec123cf6f5c456e1e27b9"
}

cURL Example:

bash
curl -X POST "https://api.dev.smach.science/artworks/674ebf66cf6f5c456e1e27a8/monitorings/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "start",
    "severity": "info",
    "date": "2025-01-08T10:00:00Z",
    "location": {
      "latitude": 49.276,
      "longitude": -0.702
    },
    "sourceType": "monitoring",
    "source": "674ec123cf6f5c456e1e27b9"
  }'

Response:

json
{
  "id": "674ec200...",
  "organization": "bayeux",
  "artwork": "674ebf66cf6f5c456e1e27a8",
  "monitoring": "674ec123cf6f5c456e1e27b9",
  "type": "start",
  "severity": "info",
  "date": "2025-01-08T10:00:00Z",
  "location": {
    "latitude": 49.276,
    "longitude": -0.702
  },
  "sourceType": "monitoring",
  "source": "674ec123cf6f5c456e1e27b9"
}

What happens:

  • ✅ Event saved with start type
  • ✅ Monitoring status updated: pendingin_progress
  • ✅ Artwork status updated: standbymonitoring
  • Recording officially started
  • ✅ SSE notification sent to web app users
  • ✅ StaRT sends Bluetooth command to start dataloggers

Phase 3: Monitoring - Push Events During Journey

While the monitoring is in_progress, push events for tracking:

3.1 Position Event (GPS Tracking)

Frequency: Every 5-15 minutes (configurable via loggerConfig.frequency)

Source-Based Routing

StaRT doesn't need to track monitoring IDs for position events! Backend automatically finds the active monitoring using the logger IMEI.

Request Body:

json
{
  "type": "position",
  "severity": "info",
  "date": "2025-01-08T12:00:00Z",
  "location": {
    "latitude": 49.443,
    "longitude": -1.266
  },
  "sourceType": "logger",
  "source": "IMEI-LOGGER-001"
}

cURL Example:

bash
curl -X POST "https://api.dev.smach.science/artworks/674ebf66cf6f5c456e1e27a8/monitorings/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "position",
    "severity": "info",
    "date": "2025-01-08T12:00:00Z",
    "location": {
      "latitude": 49.443,
      "longitude": -1.266
    },
    "sourceType": "logger",
    "source": "IMEI-LOGGER-001"
  }'

Response: 200 OK (event saved, monitoring unchanged)

Position Events NOT Streamed via SSE

Position events are NOT included in SSE streaming (too frequent). Use REST polling (GET /monitorings/{id}/events) to fetch position history.

3.2 Alert Event (Threshold Violation)

When a sensor detects a threshold breach:

Source-Based Routing

Backend automatically finds the active monitoring using the sensor IMEI.

Request Body:

json
{
  "type": "alert",
  "severity": "warning",
  "date": "2025-01-08T15:30:00Z",
  "location": {
    "latitude": 48.856,
    "longitude": 2.352
  },
  "sourceType": "sensor",
  "source": "IMEI-SENSOR-002",
  "value": 25.5,
  "message": "high_temperature"
}

cURL Example:

bash
curl -X POST "https://api.dev.smach.science/artworks/674ebf66cf6f5c456e1e27a8/monitorings/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "alert",
    "severity": "warning",
    "date": "2025-01-08T15:30:00Z",
    "location": {
      "latitude": 48.856,
      "longitude": 2.352
    },
    "sourceType": "sensor",
    "source": "IMEI-SENSOR-002",
    "value": 25.5,
    "message": "high_temperature"
  }'

Response: 200 OK (alert saved, SSE notification sent to web app)

Alert Message Types:

  • high_temperature - Temperature above max threshold
  • low_temperature - Temperature below min threshold
  • high_humidity - Humidity above max threshold
  • low_humidity - Humidity below min threshold
  • vibration_alert - Accelerometer threshold exceeded

3.3 Notification Event (Manual Message) (v1.0.0)

For manual messages from the carrier/operator:

Request Body:

json
{
  "type": "notification",
  "severity": "info",
  "date": "2025-01-08T14:45:00Z",
  "location": {
    "latitude": 50.718,
    "longitude": -1.881
  },
  "sourceType": "user",
  "source": "admin@bayeux.test",
  "message": "Rest stop for lunch - All systems nominal",
  "tag": "Road conditions"
}

Response: 200 OK (notification saved, SSE broadcast to organization)


Phase 4: Stop - End Recording

4.1 Stop Recording - POST Stop Event

Cannot Restart After Stop

Once a monitoring is stopped (ended status), it CANNOT be restarted. This is a business rule to ensure monitoring session immutability.

Endpoint: POST /artworks/{artworkId}/monitorings/events

Request Body:

json
{
  "type": "stop",
  "severity": "info",
  "date": "2025-01-08T22:00:00Z",
  "location": {
    "latitude": 51.507,
    "longitude": -0.127
  },
  "sourceType": "monitoring",
  "source": "674ec123cf6f5c456e1e27b9"
}

cURL Example:

bash
curl -X POST "https://api.dev.smach.science/artworks/674ebf66cf6f5c456e1e27a8/monitorings/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "stop",
    "severity": "info",
    "date": "2025-01-08T22:00:00Z",
    "location": {
      "latitude": 51.507,
      "longitude": -0.127
    },
    "sourceType": "monitoring",
    "source": "674ec123cf6f5c456e1e27b9"
  }'

Response:

json
{
  "id": "674ec204...",
  "organization": "bayeux",
  "artwork": "674ebf66cf6f5c456e1e27a8",
  "monitoring": "674ec123cf6f5c456e1e27b9",
  "type": "stop",
  "severity": "info",
  "date": "2025-01-08T22:00:00Z",
  "location": {
    "latitude": 51.507,
    "longitude": -0.127
  },
  "sourceType": "monitoring",
  "source": "674ec123cf6f5c456e1e27b9"
}

What happens:

  • ✅ Event saved with stop type
  • ✅ Monitoring status updated: in_progressended
  • ✅ Artwork status updated: monitoringready
  • Monitoring session closed (immutable, cannot restart)
  • ✅ Dataloggers marked as AVAILABLE in inventory
  • ✅ SSE notification sent to web app users
  • ✅ StaRT sends Bluetooth command to stop dataloggers
  • ✅ Artwork ready for new monitoring session

Post-Stop Actions

  • Take photos AFTER pressing STOP
  • Upload photos to S3 separately (v1.0.0)
  • Later: Upload datalogger data via USB (v1.0.0)

Phase 5: Query Events (Timeline)

5.1 Get All Events for Monitoring

bash
curl -X GET "https://api.dev.smach.science/monitorings/674ec123cf6f5c456e1e27b9/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux"

Response:

json
[
  {
    "id": "674ec200...",
    "type": "start",
    "date": "2025-01-08T10:00:00Z",
    "location": {"latitude": 49.276, "longitude": -0.702}
  },
  {
    "id": "674ec201...",
    "type": "position",
    "date": "2025-01-08T12:00:00Z",
    "location": {"latitude": 49.443, "longitude": -1.266}
  },
  {
    "id": "674ec202...",
    "type": "alert",
    "date": "2025-01-08T15:30:00Z",
    "location": {"latitude": 48.856, "longitude": 2.352},
    "value": 25.5,
    "message": "high_temperature"
  },
  {
    "id": "674ec203...",
    "type": "stop",
    "date": "2025-01-08T22:00:00Z",
    "location": {"latitude": 51.507, "longitude": -0.127}
  }
]

5.2 Real-Time Event Stream (SSE)

For real-time monitoring in the web app (and optionally StaRT):

bash
curl -X GET "https://api.dev.smach.science/monitorings/events/stream" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux" \
  -H "Accept: text/event-stream"

Event Types Streamed:

  • start - Monitoring started
  • alert - Threshold violation
  • notification - User message (v1.0.0)
  • stop - Monitoring stopped
  • position - NOT streamed (too frequent, use REST polling)

Example SSE Message:

data: {"type":"alert","severity":"warning","date":"2025-01-08T15:30:00Z", ...}

data: {"type":"stop","severity":"info","date":"2025-01-08T22:00:00Z", ...}

Heartbeat: Empty SSE every 30s to keep connection alive


Error Handling

Common Errors

1. No Active Monitoring Found

json
{
  "status": 404,
  "error": "No active monitoring found for artwork 674ebf66cf6f5c456e1e27a8"
}

Solution: Create monitoring with POST /artworks/{id}/monitorings first

2. Artwork Already Has Active Monitoring

json
{
  "status": 400,
  "error": "Artwork 674ebf66cf6f5c456e1e27a8 already has an active monitoring"
}

Solution: Complete current monitoring before creating a new one

3. Cannot Restart Ended Monitoring

json
{
  "status": 400,
  "error": "Monitoring 674ec123cf6f5c456e1e27b9 has status Ended and cannot be restarted"
}

Solution: Create a new monitoring session

4. Invalid Source for Event Type

json
{
  "status": 400,
  "error": "alert events must have sourceType=sensor"
}

Solution: Use correct sourceType for event type (see table below)

5. Sensor Not Associated with Active Monitoring

json
{
  "status": 404,
  "error": "No active monitoring found for sensor IMEI-SENSOR-002"
}

Solution: Verify sensor IMEI is correctly associated with monitoring during Setup

6. Missing X-Organization Header

json
{
  "status": 400,
  "error": "X-Organization header required for multi-organization users"
}

Solution: Include X-Organization: bayeux header


Event Types & Source Routing

Event TypesourceTypesourceWhen to Send
startmonitoringmonitoring-uuidOnce: Begin recording
alertsensorIMEI-SENSOR-xxxOn threshold violation
positionloggerIMEI-LOGGER-xxxEvery 5-15 min during journey
notificationuseremail@domain.testManual user message (v1.0.0)
stopmonitoringmonitoring-uuidOnce: End recording

Source-Based Routing Benefits:

  • StaRT doesn't need to track monitoring IDs for sensor/logger events
  • Backend automatically finds active monitoring using device IMEI
  • Simpler mobile app logic

Status Summary

Monitoring Status

StatusDescriptionArtwork StatusCan Send EventsNext Actions
pendingSetup complete, awaiting STARTstandby✅ Only startPress START button
in_progressRecording in progressmonitoringposition, alert, notification, stopContinue journey or press STOP
endedRecording stoppedready❌ NoneUpload data (v1.0.0)
uploadedData uploaded to S3 (v1.0.0)analysing❌ NoneExpert analysis
completedExpert analysis done (v1.0.0)ready/archived❌ NoneCreate new monitoring

Artwork Status

StatusDescriptionMonitoring StatusNext Actions
draftBeing configuredNoneConfigure artwork
readyConfigured, no active monitoringNoneCreate monitoring (Setup)
standbyMonitoring created, awaiting STARTpendingPress START
monitoringActive monitoring sessionin_progressContinue or press STOP
analysingData uploaded, awaiting analysis (v1.0.0)uploadedExpert analysis
archivedNo longer monitoredcompletedArchive

Complete Example Workflow

bash
# 0. Authentication (with organization scope)
TOKEN=$(curl -X POST "https://id.smach.science/realms/smach/protocol/openid-connect/token" \
  -d "client_id=start" \
  -d "username=admin@bayeux.test" \
  -d "password=PASSWORD" \
  -d "grant_type=password" \
  -d "scope=openid organization" | jq -r '.access_token')

# 1. List artworks ready for setup
curl -X GET "https://api.dev.smach.science/artworks?status=ready" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux"

# 2. Setup - Create monitoring
curl -X POST "https://api.dev.smach.science/artworks/674ebf66cf6f5c456e1e27a8/monitorings" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux" \
  -H "Content-Type: application/json" \
  -d '{
    "organization": "bayeux",
    "artwork": "674ebf66cf6f5c456e1e27a8",
    "type": "transport",
    "status": "pending",
    "dataloggers": [...],
    "config": {...}
  }'

# Store monitoring ID
MONITORING_ID="674ec123cf6f5c456e1e27b9"

# 3. Start - Begin recording
curl -X POST "https://api.dev.smach.science/artworks/674ebf66cf6f5c456e1e27a8/monitorings/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "start",
    "severity": "info",
    "date": "2025-01-08T10:00:00Z",
    "location": {"latitude": 49.276, "longitude": -0.702},
    "sourceType": "monitoring",
    "source": "'"$MONITORING_ID"'"
  }'

# 4. Position - During journey
curl -X POST "https://api.dev.smach.science/artworks/674ebf66cf6f5c456e1e27a8/monitorings/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "position",
    "severity": "info",
    "date": "2025-01-08T12:00:00Z",
    "location": {"latitude": 49.443, "longitude": -1.266},
    "sourceType": "logger",
    "source": "IMEI-LOGGER-001"
  }'

# 5. Alert - Threshold exceeded
curl -X POST "https://api.dev.smach.science/artworks/674ebf66cf6f5c456e1e27a8/monitorings/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "alert",
    "severity": "warning",
    "date": "2025-01-08T15:30:00Z",
    "location": {"latitude": 48.856, "longitude": 2.352},
    "sourceType": "sensor",
    "source": "IMEI-SENSOR-002",
    "value": 25.5,
    "message": "high_temperature"
  }'

# 6. Stop - Arrival
curl -X POST "https://api.dev.smach.science/artworks/674ebf66cf6f5c456e1e27a8/monitorings/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "stop",
    "severity": "info",
    "date": "2025-01-08T22:00:00Z",
    "location": {"latitude": 51.507, "longitude": -0.127},
    "sourceType": "monitoring",
    "source": "'"$MONITORING_ID"'"
  }'

# 7. Query events timeline
curl -X GET "https://api.dev.smach.science/monitorings/$MONITORING_ID/events" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Organization: bayeux"

Next Steps for Jay

  1. Review this workflow and validate against StaRT mobile app architecture
  2. Test authentication with admin@bayeux.test credentials
  3. Implement Bluetooth detection for Logger+Sensor pairs
  4. Test Setup endpoint (POST /artworks/{id}/monitorings)
  5. Test event endpoints (Start, Position, Alert, Stop)
  6. Integrate SSE streaming for real-time alerts (optional for mobile)
  7. Test with Bayeux fixture data (see bayeux-test-dataset)

Meeting: Monday, December 9, 2024 - API review with Jay

Beta Test: January 8, 2025 - Fake Bayeux Tapestry transport to London


Additional Resources

Science & Mechanics in Conservation of Heritage