vCar API call guide

How to drive a KX virtual car from your own code, using the Passenger Welcome function as the example. Full reference: KX360v vCar REST API Reference.

Before you start

1. Get an API key. Sign in to the KX platform, open your account menu, go to API keys and create a personal key. It starts with sk_live_ and is shown once, so copy it to a safe place. The key acts as you: it can do what your account can do, nothing more. Delete it there when you no longer need it.

2. Send it on every call as a header:

Authorization: Bearer sk_live_…

3. Use your environment's address. On KX Alpha it is https://vcar.alpha.kaizenics.com. Every vCar route starts with /api/instance/{id}, where {id} is your vCar's instance id.

BASE=https://vcar.alpha.kaizenics.com
ID=psw-360-instance-00000000          # the Passenger Welcome vCar on Alpha
H="Authorization: Bearer $KX_API_KEY"
The demo page next door makes these same calls. It holds a key on the server for you, so it can only touch this one vCar and a few signals. With your own key you call the API directly.

The story

Passenger Welcome: the driver's phone sends a welcome message with a profile and a seat position. The central computer (CentralHPC) reacts by commanding the seat (SeatECU) and the ambient light (LightingControlECU). A door command asks DoorECU to open the door, and it reports the door angle back. The steps below follow that story.

1 · Is the vCar running?

curl -s -H "$H" $BASE/api/instance

Lists the vCars you can see with their state (RUNNING, STOPPED, READY, DEGRADED…). Trimmed:

{"instances":[{"instance_id":"psw-360-instance-00000000","vac_name":"psw-bench01",
  "state":"RUNNING","containers":{"total":8,"running":8,"exited":0,"other":0}}]}

Start or stop the whole vCar (both answer 202 at once and work in the background; poll step 1 until the state changes):

curl -s -X POST -H "$H" $BASE/api/instance/$ID/start
curl -s -X POST -H "$H" $BASE/api/instance/$ID/stop

2 · Which ECUs does it have?

curl -s -H "$H" $BASE/api/instance/$ID/ecus
{"instance_name":"PSW.Bench01","counts":{"total":5,"running":5},
 "ecus":[{"ecu_name":"CentralHPC","state":"running","model":"behaviour","diag_available":true},
         {"ecu_name":"DoorECU","state":"running", …},
         {"ecu_name":"LightingControlECU", …},{"ecu_name":"SeatECU", …}, …]}

3 · Control one ECU

curl -s -X POST -H "$H" $BASE/api/instance/$ID/ecus/DoorECU/stop
curl -s -X POST -H "$H" $BASE/api/instance/$ID/ecus/DoorECU/start
curl -s -X POST -H "$H" $BASE/api/instance/$ID/ecus/DoorECU/restart   # values back to the YAML

Each answers at once with the container's new state. Other ECUs keep running.

4 · Read an ECU's state and parameters

curl -s -H "$H" $BASE/api/instance/$ID/ecus/DoorECU/state
{"ecu_name":"DoorECU","available":true,
 "state":{"angle":0,"target":0},
 "parameters":{"open_angle":90,"angle_step":5}, "dids":[…]}

State variables change while the ECU runs. Parameters are settings the ECU's rules read.

5 · Change a parameter on the running ECU

curl -s -X PATCH -H "$H" -H 'content-type: application/json' \
  -d '{"open_angle": 60}' $BASE/api/instance/$ID/ecus/DoorECU/state

The body is a flat map of names to values; state variables and parameters use the same call. Read step 4 again to see the new value. A restart puts it back.

6 · Read a signal on the bus

curl -s -H "$H" "$BASE/api/instance/$ID/signals/read?namespace=CentralHPC-BodyCAN&signal_name=PW_DoorStatus.DoorAngle"
{"status":"success","namespace":"CentralHPC-BodyCAN","signal_name":"PW_DoorStatus.DoorAngle","value":0}

Signal names are Frame.Signal. The namespace is {ECU}-{bus}; any ECU on the bus sees the same value.

7 · Send the welcome (write signals)

curl -s -X POST -H "$H" -H 'content-type: application/json' $BASE/api/instance/$ID/signals/restbus \
  -d '{"namespace":"CentralHPC-BodyCAN","signal_name":"PW_Welcome.SeatPosTarget","value":40}'
curl -s -X POST -H "$H" -H 'content-type: application/json' $BASE/api/instance/$ID/signals/restbus \
  -d '{"namespace":"CentralHPC-BodyCAN","signal_name":"PW_Welcome.ProfileId","value":1}'
{"status":"success","namespace":"CentralHPC-BodyCAN","signal_name":"PW_Welcome.ProfileId","value":1.0}

restbus keeps sending the value, so it stays on the bus. Write only signals whose real sender is outside the car (a phone, a key, a door handle); an ECU's own output is changed through that ECU (step 5).

8 · Read the answers

curl -s -H "$H" $BASE/api/instance/$ID/ecus/CentralHPC/state
curl -s -H "$H" "$BASE/api/instance/$ID/signals/read?namespace=CentralHPC-BodyCAN&signal_name=PW_SeatCmd.SeatPosTarget"
curl -s -H "$H" "$BASE/api/instance/$ID/signals/read?namespace=CentralHPC-BodyCAN&signal_name=PW_AmbientLightCmd.AmbientReq"
{"ecu_name":"CentralHPC","state":{"active_profile":1,"commanded_light_level":8},"parameters":{"welcome_light_level":8}, …}

Then open the door and watch its angle:

curl -s -X POST -H "$H" -H 'content-type: application/json' $BASE/api/instance/$ID/signals/restbus \
  -d '{"namespace":"CentralHPC-BodyCAN","signal_name":"PW_DoorCmd.OpenDoor","value":1}'
curl -s -H "$H" "$BASE/api/instance/$ID/signals/read?namespace=CentralHPC-BodyCAN&signal_name=PW_DoorStatus.DoorAngle"

Put everything back when you are done: write 0 to PW_Welcome.ProfileId, PW_Welcome.SeatPosTarget and PW_DoorCmd.OpenDoor.

When something goes wrong

Interactive API docs: $BASE/docs (same key). Full reference with every route: KX360v vCar REST API Reference.