TCPP 1.3.0
JSON Schema draft 2020-12 · 55 files Draft

Schema

The TCPP 1.3.0 message format

Twenty-seven endpoints, each a request/response pair, plus all.json, the envelope every one of them shares. Every file is served here at the URL its $id names, so $ref resolves without rewriting.

The envelope

Every TCPP message is one JSON object with the same five or six top-level members. The endpoint decides what goes in record; everything around it is identical whether the message reports a charging session or answers a ping.

MemberInWhat it holds
tcppboth The version this message is written against, as a URL: https://tcpp.digital/schema/1.3.0/.
headboth Who, to whom, about what, when, and with what outcome. Identical in shape across all endpoints; described below.
recordboth The payload, defined by the endpoint's own schema. This is the only member whose shape changes.
parsedresponse Per-element outcome: a map from a path in the request to a six-digit error code, so a partially accepted message says exactly which part failed.
participantsboth Other parties to the process, each with its type, id and permissions (read, control, push, broker…), optionally naming a forwarder and an approver.
referencesboth The messages this one relates to: each a reference id, a full copy of that message's head, and optionally its signature. This is what makes a process reconstructable from its records.

The head

Twelve required fields. A response repeats the request's head with the direction reversed, origin and target swapped, and its own outcome in error_code.

FieldTypeMeaning
record_typestringThe endpoint: ping, charge_start, tariffs_list, …
record_directionstringrequest, response or internal. Every request has a response; internal is for the exceptions, such as an error a device records about itself.
record_udtdate-timeUniversal date and time of the record, with offset.
record_paginationnumberThe sender's own counter for this record, from 1 upwards.
record_versionstringThe TCPP version: 1.3.0.
origin_typestring(3)The sender's module type. See the table below.
origin_idstringThe sender's identifier, prefixed by its namespace.
target_typestring(3)The recipient's module type.
target_idstringThe recipient's identifier.
context_typestring(3)What kind of process this message belongs to: a process type, not a module type. May be empty.
context_idstringThe identifier of that process, shared by every message in it. May be empty.
error_codehex(6)The outcome. 000000 in a request and in a response that succeeded.
error_textstringOptional plain text alongside the code.

Identifiers

Every id in a head (origin, target, context, participants) carries a one-letter prefix and a colon, naming the namespace it belongs to, so an identifier is never ambiguous about what kind of thing it names. The whole id, prefix included, is at most 120 characters.

PrefixNamespaceExample
E:EVSE IDE:DE*PID*E*IWS*00100017
G:GUIDG:90676293-fa28-49bd-81ba-1b58a0f62abd
D:Domain namespaceD:node.example.de
P:Private namespaceP:ECS-HOST
I:Internal to the senderI:slot-2
H:HashH:9f86d081884c7d…
N:Numeric paginationN:45330
C:Contract or tariff idC:DE-8AA-C12345-6
V:Vehicle idV:WDD1234567A123456
X:UndefinedX:legacy-7

Module types

Three upper-case letters identify what a participant is. The type says which role a party plays in the protocol; the id says which one it is.

Trusted services

TypeModuleHolds
TMHTrusted Management HostKeys, modules, eMAIDs, charge points
TEHTrusted Exchange HostDynamic data: status, reservations
TAHTrusted Archive HostArchived documents and records

Market participants

TypeModuleNotes
MSPeMobility Service ProvidereMSP
CPOCharge Point OperatorWhere independent of the MSP
LMPLocation Management ProviderParking space
FMPFleet Management ProviderFleet and logistics
ESPEnergy Supplier ProviderEnergy supplier
SMSSupport Monitoring ServiceTechnical service and monitoring
SASSurveillance Authority ServiceAuthorities

Charge points and local devices

TypeModuleNotes
CSUCharge Switch UnitThe main charge point device
CCUCharge Central UnitCentre of a satellite system
LIULocal Identification UnitWhere independent of the CSU
LDULocal Display UnitWhere independent of the CSU
RIURemote Identification UnitApp, telematics, external display
RDURemote Display UnitApp, telematics, external display
PSUParking Space UnitCar park, parking garage or lot
DEVDeviceAny other device

Metering and energy management

TypeModuleNotes
SMGSmart Meter GatewayBSI TR-03109
SMLSmart Meter Light
ELMElectric MeterIndependent meter
EMUEnergy Management UnitLocal load control
GMUGrid Energy Management UnitGrid-side load management
BMUBattery Management UnitBattery storage

Context types

context_type names the kind of process a message belongs to, and is drawn from a separate set: CRG charging · ENG energy control · MNT maintenance · INF information · DRR data request record · TFF tariff.

Error codes

Six hexadecimal digits, used in the head, in the per-element parsed block of a response and in references. The code is read in three parts: the first digit is the global class, the next two the detailed status, and the last three a module-specific status, FFF where the module is not identified.

Digit 1Class
0No error
1Not able to parse
2Head data
3Record parsing
4Record building
5Signature conversion or delivery
6Internal software error
7Internal hardware error
FUnknown

So 000000 is success and FFFFFF is an unknown failure. A response that accepted the head but rejected one array element says so in parsed, keyed by the path to that element, rather than failing the whole message.

The two places spell the code differently. In a head, error_code is upper-case hexadecimal and nothing else: ^[0-9A-F]{6}$. The values inside parsed are looser — either case, and an optional leading #. A head carrying ffffff fails validation; the same string in parsed passes.

Signing

A TCPP message travels as a compact JWS with alg: ES384, ECDSA over the NIST P-384 curve with SHA-384. The JSON object above is the payload; the receiver decodes it, checks it against the sender's public key, and keeps both the message and the token it arrived in.

The payload bytes are signed as they were composed. A verifier must check the signature over the bytes it received, never over a re-serialisation of the parsed object: key order, spacing and number formatting all change under a round-trip, and the signature does not survive it.

JWS signatures use the fixed-width R‖S encoding of IEEE P1363, which is what a browser's Web Crypto produces. Libraries that emit DER, Go's ecdsa.SignASN1 among them, need converting first, including the left-padding of a short coordinate.

A signature can also be carried inside a message: each entry in references may hold the jws of the record it refers to, so a chain of records can be handed on as one document and still be checked link by link. Note that this member is an object, not the compact string a message travels as: inside a record the signature is carried in the JSON serialisation of JWS, so that it stays readable as JSON rather than as one opaque line.

Endpoints

Twenty-seven request/response pairs. Each name below links to its two schema files.

Charging

EndpointWhat it carriesSchema
charge_startOpening a charging process: the base data of the session and the legal subjects party to it. request · response
charge_processThe process itself: status, events, display, measurement curves and legal subjects. request · response
charge_eventA single event within a running process, up to and including its end. request · response
emaid_getResolving a contract identity: by card, by vehicle or by another form of enquiry. request · response
tariffs_listTariffs for charge points, searched by identifier, by location or by charging limits. request · response

Metering

EndpointWhat it carriesSchema
measurement_createCreating a measurement configuration record, a meter's or charge point's digital self-description: what it is, what hardware it has found, which software it runs, which documents it refers to. request · response
measurement_changeSuperseding one configuration record with the next, leaving the old one findable. request · response
measurement_configurationReading a configuration record back: the anchor every later message about that device refers to. request · response

Identity, keys and verification

EndpointWhat it carriesSchema
key_getThe public key of a module, so its signatures can be checked. request · response
module_getWhat a module is: its type, its id and the details filed about it. request · response
verification_getThe verifications recorded for a module: who attested what, and when. request · response
verification_setFiling a verification against a module, naming the administrator responsible. request · response

Configuration

EndpointWhat it carriesSchema
parameters_getReading named parameters. request · response
parameters_setWriting parameters, naming the administrators who authorised it. request · response
parameters_deleteRemoving parameters, likewise attributed. request · response
parameters_listListing parameters over a range, with a result limit. request · response
trigger_setInstalling a trigger: formulas to evaluate and actions to take when they hold. request · response
trigger_getReading one trigger back. request · response
trigger_deleteRemoving a trigger. request · response
triggers_listListing triggers over a range. request · response

Operation

EndpointWhat it carriesSchema
pingLiveness. The smallest message in the set, and the one to implement first. request · response
statusOne or more statuses, counted and signed, referring back to what they describe. request · response
errorErrors as their own record: counted, referenced and reportable in their own right. request · response
display_outputWhat a display should show. request · response
display_inputWhat was entered on one. request · response

Archive

EndpointWhat it carriesSchema
archive_listSearching archived records by head and by content, over a time range and with a result limit. request · response
archive_getRetrieving one archived record, with or without the signature it was filed under. request · response

The envelope schema

all.json is the base format the others specialise: the head, the participant and reference definitions, and a free-form record. Validate against it when you need to read a message whose endpoint you do not implement.

Getting the files

All 55 files, as served here, are also packaged as one archive. The reference node embeds the same set and serves it at the same paths, so an implementation can be developed against a local copy and moved to the published URLs unchanged.