Integration guide

Connect your CSMS to Tagless.

Tagless receives plug-in events from an existing CSMS, returns a current challenge, matches OEM vehicle telemetry, and exposes the identification decision.

Base URL https://api.tagless.no/api/v1
CSMS role Detect plug-in, apply the challenge, report when it became active, act on the decision.
Tagless role Create session, generate challenge, match OEM telemetry, return decision and evidence.
API access Use a per-CSMS bearer key. Keep VIN mapping on a separate CSMS-scoped mapping secret.

Boundary of responsibility

Tagless is not a replacement for your CSMS or OCPP stack. It is an identification layer that plugs into your existing session flow.

System Owns
CSMS / OCPP backend Charger communication, OCPP messages, safety limits, smart charging profile construction, transaction state, and final action on the Tagless decision.
Tagless PoC session creation, challenge generation, OEM telemetry correlation, location/current matching, decisioning, diagnostics, and evidence export.
Important: Tagless returns challenge periods. Your CSMS decides how to apply those periods to the charger.

Security and customer mapping

Each CSMS client gets a Tagless API key for request authentication. The key identifies the calling CSMS and lets Tagless track pilot usage, failures, and evidence by integration partner.

Authorization: Bearer <csms_api_key>

Vehicle/customer mapping uses a separate secret. Do not use the API key as the VIN hashing secret, because API keys are operational credentials that need rotation and revocation semantics.

Identifier Purpose
tagless_vehicle_ref Stable Tagless reference for a linked tester vehicle. Useful when the CSMS stores Tagless vehicle mappings during onboarding.
vin_hash Partner-scoped HMAC-SHA256 hash of the normalized VIN. Useful when the CSMS already stores customer VINs and can derive the same hash.
vehicle_id_hash Internal PoC telemetry identifier. It can appear in evidence, but CSMS customer mapping should prefer tagless_vehicle_ref or vin_hash.
Mapping rule: vin_hash = HMAC-SHA256(csms_vehicle_mapping_secret, uppercase(trim(vin))). Hashes are scoped per CSMS, so two CSMS partners cannot compare vehicle lists by hash.

Integration flow

The minimal integration uses three CSMS-facing calls.

1

Plug-in detected

Your CSMS starts a provisional Tagless identification session and posts plug-in time, charger location, and supported current range.

2

Challenge applied

Tagless returns a current sequence. Your CSMS either applies it and reports the result, or reports that it chose not to start.

3

Decision read

Your CSMS polls the decision endpoint during the identification window.

4

Customer mapped

On success, your CSMS maps the returned vehicle reference or VIN hash to its customer. On failure, it uses its fallback flow.

Endpoints

POST /api/v1/csms/plug-in

Create a PoC session and receive a Tagless challenge.

POST /api/v1/csms/sessions/{session_id}/challenge-status

Report the result for the full challenge application. Accepted challenges need timing; a CSMS no-start should include a reason.

GET /api/v1/csms/sessions/{session_id}/decision

Read the current Tagless identification decision for the session.

Timing fields

Accurate timing is essential because Tagless compares OEM telemetry with the expected challenge windows.

Field Meaning
csms_sent_at When your CSMS sent or committed the charger-control command for the challenge.
charger_response_at When your CSMS received or determined the charger response.
challenge_started_at When the first challenge period became active. Tagless uses this as the matching anchor.

For an absolute OCPP 1.6 smart charging schedule, challenge_started_at usually matches chargingSchedule.startSchedule. For a relative schedule, use the best CSMS timestamp for when the challenge actually starts taking effect.

If your CSMS decides not to start the provisional charging session, report status: not_started with a short reason and do not invent timing fields.

Payload examples

The minimum plug-in request needs plug-in timestamp, charger location, and supported current range. Charger, connector, site, and CSMS session ids are useful evidence fields and are included below.

1. Create a session

POST https://api.tagless.no/api/v1/csms/plug-in
Authorization: Bearer <csms_api_key>
Content-Type: application/json

{
  "csms_session_id": "tx-provisional-789",
  "charger_id": "EVCHARGE-001",
  "connector_id": 1,
  "site_id": "RIGA-TEST-01",
  "plug_in_detected_at": "2026-05-21T12:00:00.000Z",
  "min_current": 6,
  "max_current": 16,
  "latitude": 56.9496,
  "longitude": 24.1052
}

2. Receive the challenge

{
  "session_id": "poc_sess_123",
  "challenge_id": "ch_123",
  "challenge_steps": [
    { "step": 1, "current": 7, "duration_seconds": 8 },
    { "step": 2, "current": 11, "duration_seconds": 8 },
    { "step": 3, "current": 8, "duration_seconds": 8 },
    { "step": 4, "current": 14, "duration_seconds": 8 },
    { "step": 5, "current": 10, "duration_seconds": 8 }
  ],
  "max_identification_window_seconds": 90,
  "candidate_precheck": {
    "status": "strong",
    "candidate_count": 1,
    "strong_candidate_count": 1,
    "window_seconds": 300,
    "location_radius_meters": 50,
    "location_signal": "last_known_near_charger",
    "latest_location_observed_at": "2026-05-21T11:52:00+00:00",
    "latest_location_age_seconds": 480,
    "signals": [
      "charge_port_latch_engaged",
      "charging_cable_present",
      "last_known_location_near_charger"
    ],
    "reason": "last_known_oem_location_and_recent_plug_or_charging_signal_near_charger"
  }
}

The candidate precheck is an advisory, privacy-safe hint. window_seconds applies to recent activity signals such as current, charging state, cable type, and charge-port latch. Vehicle location uses the latest known OEM location, with freshness exposed through latest_location_observed_at and latest_location_age_seconds. The final decision endpoint remains authoritative.

3. Report challenge status

POST https://api.tagless.no/api/v1/csms/sessions/poc_sess_123/challenge-status
Authorization: Bearer <csms_api_key>
Content-Type: application/json

{
  "challenge_id": "ch_123",
  "csms_sent_at": "2026-05-21T12:00:03.800Z",
  "charger_response_at": "2026-05-21T12:00:04.600Z",
  "challenge_started_at": "2026-05-21T12:00:04.000Z",
  "status": "accepted",
  "csms_transaction_id": "tx-789",
  "raw_status": "Accepted"
}

If your CSMS decides not to start the provisional charging session, close the Tagless session explicitly:

POST https://api.tagless.no/api/v1/csms/sessions/poc_sess_123/challenge-status
Authorization: Bearer <csms_api_key>
Content-Type: application/json

{
  "challenge_id": "ch_123",
  "status": "not_started",
  "reason": "no_candidate_vehicles",
  "raw_status": "CSMS policy: no candidate vehicles"
}

csms_transaction_id is optional here. Include it only if your CSMS already created an internal transaction or reference before deciding not to proceed.

4. Read the decision

GET https://api.tagless.no/api/v1/csms/sessions/poc_sess_123/decision
Authorization: Bearer <csms_api_key>
{
  "session_id": "poc_sess_123",
  "decision": "identified",
  "vehicle_id_hash": "vh_abc123",
  "tagless_vehicle_ref": "tlv_abc123",
  "vin_hash": "vinh_v1_csms_riga_test_8f5d1c7d0b5a42f9",
  "vin_hash_version": "v1",
  "hash_algorithm": "HMAC-SHA256",
  "hash_scope": "csms_riga_test",
  "confidence_score": 0.99,
  "failure_reason": null,
  "latency_ms": 50800,
  "location_distance_meters": 3,
  "location_signal": "matched",
  "matcher_strategy": "timed_step",
  "matched_step_count": 5,
  "required_step_matches": 4
}

Decision handling

Decision Recommended CSMS behavior
identified Map tagless_vehicle_ref or vin_hash to the CSMS customer/contract, then continue under the configured pilot policy.
pending Wait and poll again while still inside the identification window.
not_identified Use your fallback flow, such as app, RFID, payment terminal, or manual operator handling. This can also mean Tagless refused to choose because multiple nearby vehicles matched the challenge, or that your CSMS chose not to start the provisional session.
failed Stop Tagless identification for this session and use your operational fallback. Review the failure reason in Tagless evidence.

CSMS implementation checklist

  1. Request a CSMS API key and a separate vehicle mapping secret from Tagless.
  2. Choose the CSMS event that represents plug-in or transaction start for the pilot charger.
  3. Start a provisional Tagless identification transaction or local session before customer identity is known.
  4. Map plug-in timestamp, charger location, and supported current range to the plug-in request. Charger, connector, and site IDs are useful optional evidence fields.
  5. Translate Tagless challenge periods into your charger-control mechanism.
  6. Report one challenge status call with challenge_started_at after the charger response is known, or status: not_started if your CSMS decides not to proceed.
  7. Poll the decision endpoint until the result is no longer pending, or until your CSMS timeout policy triggers.
  8. Map successful decisions by tagless_vehicle_ref or CSMS-scoped vin_hash, never by raw VIN from the decision endpoint.
  9. Store the Tagless session_id and export CSV evidence for pilot sessions.
  10. Define fallback behavior for rejected challenge, missing OEM telemetry, timeout, ambiguous candidate matches, CSMS no-start, and not identified decisions.
Next step for pilots: contact Tagless to agree on CSMS credentials, vehicle mapping, pilot charger coordinates, current limits, timeout policy, and evidence export expectations.