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. |
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. |
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.
Plug-in detected
Your CSMS starts a provisional Tagless identification session and posts plug-in time, charger location, and supported current range.
Challenge applied
Tagless returns a current sequence. Your CSMS either applies it and reports the result, or reports that it chose not to start.
Decision read
Your CSMS polls the decision endpoint during the identification window.
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
/api/v1/csms/plug-in
Create a PoC session and receive a Tagless challenge.
/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.
/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
- Request a CSMS API key and a separate vehicle mapping secret from Tagless.
- Choose the CSMS event that represents plug-in or transaction start for the pilot charger.
- Start a provisional Tagless identification transaction or local session before customer identity is known.
- 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.
- Translate Tagless challenge periods into your charger-control mechanism.
- Report one challenge status call with
challenge_started_atafter the charger response is known, orstatus: not_startedif your CSMS decides not to proceed. - Poll the decision endpoint until the result is no longer
pending, or until your CSMS timeout policy triggers. - Map successful decisions by
tagless_vehicle_refor CSMS-scopedvin_hash, never by raw VIN from the decision endpoint. - Store the Tagless
session_idand export CSV evidence for pilot sessions. - Define fallback behavior for rejected challenge, missing OEM telemetry, timeout, ambiguous candidate matches, CSMS no-start, and not identified decisions.