NAV Navbar

comma API spec

Base URL: https://api.commadotai.com/

Definitions

Dongle ID

A dongle ID is an 16-character alphanumeric device identifier. Each comma device has a unique dongle ID.

Segment

A segment is one minute of driving. openpilot rotates log and camera files at this interval. Segments are numbered in a 0-indexed fashion.

Segment names are of the form dongle_id|YYYY-MM-DD--HH-MM-SS--N where N is the segment number. For example, 0375fdf7b1ce594d|2019-05-21--23-17-14--0.

Route

A route is a sequence of segments recorded between car ignition and power-down. Route names are of the form dongle_id|YYYY-MM-DD--HH-MM-SS. For example, 0375fdf7b1ce594d|2019-05-21--23-17-14.

Authentication

Include a JWT header of the following format in order to access authenticated endpoints:

curl -H 'Authorization: JWT {{token}}' https://api.commadotai.com/

Token can be acquired at jwt.comma.ai

Enter your token here to autofill code blocks:

Response Codes

We use conventional HTTP response codes to signal success or failure of API requests.

200 - OK
400 - Bad Request: Likely due to an invalid or missing parameter.
401 - Unauthorized: JWT token invalid.
403 - Forbidden. Authenticated user lacks access to desired entity.
404 - Not Found: Requested entity does not exist.
409 - Conflict: Entity already exists.
429 - Too Many Requests: Too many requests, too quickly. Please use exponential backoff and see per-endpoint rate limit documentation.

Account

Profile

GET /v1/me/

Returns information about the authenticated user

curl https://api.commadotai.com/v1/me/ -H 'Authorization: JWT {{token}}'
{
  "email": "commaphone3@gmail.com",
  "id": "2e9eeac96ea4e6a6",
  "points": 34933,
  "regdate": 1465103707,
  "superuser": false,
  "username": "joeyjoejoe"
}




Response

Key Type Description
"email" string Your email
"id" (string) Dongle ID
"points" (integer) Number of comma points
"regdate" (integer) Seconds since epoch at time of registration
"superuser" (bool) Apply for superuser here
"username" (string) Your username

Devices

GET /v1/me/devices/

List devices owned or readable by authenticated user

curl https://api.commadotai.com/v1/me/devices/ -H 'Authorization: JWT {{token}}'





Response

[
  {
    "alias": "Comma EON",
    "device_type": "neo",
    "dongle_id": "4bba516fb4439b31",
    "is_owner": true,
    "is_paired": true,
    "last_gps_accuracy": 12,
    "last_gps_bearing": 0,
    "last_gps_lat": 32.0,
    "last_gps_lng": -117.0,
    "last_gps_speed": 0,
    "last_gps_time": 1558583671000,
    "last_segment_create_time": 1557180193,
    "last_segment_utc_millis": 1554179182574,
    "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDLI++RMXz29fBPNdECbCL8SGQ1+O/y1xhLsm/XsApxlghsKiWFSXiLJbHkHFOhQb6F421pVMZI0NtVXK5hUmwaAYLVg644/sLv/J32iW2vvdntT6GRTJxJr4LvbuXuBggW2sIYINFOOKng71CO5BxUNn+WNmeYFSqblFi4HjIuGbUZABuF9t0nkjMMVDZm9pTeeWqJtC4BxlACmJPA/88bdsiq4VDZ51yWqXxKJAq1HpG8RXpBs2leNQfnqF/mwtAkSeatqJYTjNAv77lFVg0rOQ6XjDLGdtRiloD+mNnJa1CJF4NiUG7hY/mdmolE4ML9W8YYX1aHNROmZApAt+Bn root@localhost\n",
    "vehicle_id": null
  },
  {
    "alias": "Toyota RAV4 EON Gold",
    "device_type": "neo",
    "dongle_id": "b0c9d2329ad1606b",
    "is_owner": false,
    "is_paired": true,
    "last_gps_accuracy": 10,
    "last_gps_bearing": 323,
    "last_gps_lat": 32.0,
    "last_gps_lng": -117.0,
    "last_gps_speed": 26.64,
    "last_gps_time": 1558736867000,
    "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCUl0gKppV0TivHeL3PPqHeA2boPhKleJNdNWd5OeOhcD5N0Wsk9DLI/iBhbM1Q+LfJJsjBoJ+V/Hs9sSnIS04nuwaQMoj75gV+HwmVfBHY+UnGKCfpLpW7PCHgeReeUKOUZzTrrxp67NJaOQtdokq2oTlX4OPMzDncNJQAECnFz8DkGQMjapJVa6ctNuANaJscjlwokz4TYHlQAktb7WZoi4iRJMi6bR6HSb3R7uflrUbnS5OyebKLr6ZbhHPIy22rILXju/15XRhRPxfAjOPBXg+/WFwSBb3j6bL6TLbShXrJOsV6NrN7+Z0C3V6ZeH7SXl8Cua7FV0l7XodkDXaf root@localhost\n",
    "vehicle_id": 6959,
    "last_segment_create_time": 1557180193,
    "last_segment_utc_millis": 1554179182574
  }
]

Response

JSON array of devices, sorted by key "last_segment_utc_millis" descending

Key Type Description
"dongle_id" (string) see Dongle ID
"alias" (string) Globally unique device nickname
"is_paired" (bool) Device has an owner
"is_owner" (bool) Authed user has write-access to device
"public_key" (string) 2048-bit public RSA key
"vehicle_id" (integer) see Vehicle by ID
"device_type" (string) one of ("neo", "panda", "app")
"last_gps_time" (integer) Milliseconds since epoch of last gps. Updates upon successful call to device location endpoint
"last_gps_lat" (float) Latitude of last location
"last_gps_lng" (float) Longitude of last location
"last_gps_accuracy" (float) Accuracy (m) of last location
"last_gps_speed" (float) Speed (m/s) at last location
"last_gps_bearing" (float) Direction of last location in degrees from north
"last_segment_create_time" (integer) Seconds since epoch of most recent call to Upload URL for a segment
"last_segment_utc_millis" (integer) Milliseconds since epoch of most recent segment start time, from GPS.

Device

Device Info

GET /v1.1/devices/:dongle_id/

Returns an object representing a comma device.

curl https://api.commadotai.com/v1.1/devices/0375fdf7b1ce594d/ -H 'Authorization: JWT {{token}}'




Response

{
  "dongle_id": "0375fdf7b1ce594d",
  "alias": "Accord EON Gold",
  "is_paired": true,
  "is_owner": false,
  "public_key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDy3qndOTobXV/f99QBJasvpwYBi357SP9wTZ1QTaezlv7us2zJNRrkZZU6Myu8BQKAoaUfE8ttWUMcj+/U94ZfYrCKQYv7lKuxAkkCWrYxRy7DfrWJNoq43zHIoaBAbpEXigJMhR2VmKwM0uPw2TFhXVTjeF+o77zOZYjxQUTU5BsQGR4CQMd2keuB6pjHua2VBP9mmdDksWg5fXZWo7RbwzZaLeDJY/9yI5QguqivGnYA6QM+9DPQlfbQ8PtxKuwQSiHTBvrxn+nzJKNuGlyxzjr1ca1uRZtV86I22mphn1rrYOg4Rb19tIM+bgmwZWOFu2yK/wRgFMnmcX4KhiQZ root@localhost\n",
  "device_type": "neo",
  "vehicle_id": 3322,
  "last_gps_time": 1558595762000,
  "last_gps_lat": 32.0,
  "last_gps_lng": -117.0,
  "last_gps_accuracy": 3,
  "last_gps_speed": 0,
  "last_gps_bearing": 0
}

Response

Key Type Description
"dongle_id" (string) see Dongle ID
"alias" (string) Globally unique device nickname
"is_paired" (bool) Device has an owner
"is_owner" (bool) Authed user has write-access to device
"public_key" (string) 2048-bit public RSA key
"vehicle_id" (integer) see Vehicle by ID
"device_type" (string) one of ("neo", "panda", "app")
"last_gps_time" (integer) Milliseconds since epoch of last gps. Updates upon successful call to device location endpoint
"last_gps_lat" (float) Latitude of last location
"last_gps_lng" (float) Longitude of last location
"last_gps_accuracy" (float) Accuracy (m) of last location
"last_gps_speed" (float) Speed (m/s) at last location
"last_gps_bearing" (float) Direction of last location in degrees from north

Update device properties

PATCH /v1/devices/:dongle_id/

Update device alias and/or vehicle_id

alias (string): device alias shown on https://my.comma.ai and the comma connect app vehicle_id (integer): see Vehicles

curl -X PATCH 'https://api.commadotai.com/v1/devices/02ec6bea180a4d36/' \
-d '{"alias": "new_alias", "vehicle_id": 1234}' \
-H 'Authorization: JWT {{token}}'

Response

Identical to Device Info but reflects updated fields.

Device location

GET /v1/devices/:dongle_id/location

Returns a gpsLocation ZMQ packet from the device. The API server queries Athena and caches the location for the Device Info response.

curl 'https://api.commadotai.com/v1/devices/02ec6bea180a4d36/location' \
-H 'Authorization: JWT {{token}}'

Response





{
  "dongle_id": "02ec6bea180a4d36",
  "lat": 32.0,
  "lng": -117.0,
  "time": 1558595762000,
  "speed": 0.0,
  "bearing": 0.0
}

Response

Key Type Description
"dongle_id" (string) see Dongle ID
"lat" (float) Latitude, degrees
"lng" (float) Longitude, degrees
"time" (integer) Milliseconds since epoch
"accuracy" (float) Accuracy (m)
"speed" (float) Speed (m/s)
"bearing" (float) Direction in degrees from north

Pair EON

POST https://api.commadotai.com/v2/pilotpair/

Pair a comma EON to authenticated user's account.

URLEncoded Request Body

Key Description
imei Device IMEI
serial Device Serial
pair_token JWT Token signed by your EON private key containing payload {"pair": true}
curl -F 'imei=000000000000000;serial=aaaaaaaa;pair_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6ImZvbyIsImlhdCI6MTU2MDU0OTM0MSwibmJmIjoxNTYwNTQ5MzQxLCJleHAiOjE1OTIwODUzNDF9.peoXbapsvT-W2dpNuHscJE6fqeaHtlB8owbTddzSkV0' https://api.commadotai.com/v2/pilotpair/ \
-H 'Authorization: JWT {{token}}'

Response

{"first_pair": true}

Response

Key Type Description
"first_pair" (string) True if the device was unpaired prior to this call. False if the device was previously paired by authenticated user.

Unpair device

POST /v1/devices/:dongle_id/unpair

Unpair a device. Authed user must be device owner to perform. (to check ownership, see Device Info).

curl -X POST 'https://api.commadotai.com/v1/devices/02ec6bea180a4d36/unpair' \
-H 'Authorization: JWT {{token}}'

Response





{"success": 1}

Response "success" (integer): 1 if device is unpaired. 0 if device type is not one of ("neo", "panda").

Grant device read permissions to user

POST /v1/devices/:dongle_id/add_user

Grant read permissions to a user by email. Authed user must be device owner to perform. (to check ownership, see Device Info).

curl -X POST 'https://api.commadotai.com/v1/devices/02ec6bea180a4d36/add_user' \
-d '{"email": "mycommafriend@gmail.com"}' \
-H 'Authorization: JWT {{token}}'

Response





{"success": 1}

Remove device read permissions from user

POST /v1/devices/:dongle_id/del_user

Remove read permissions from a user by email. Authed user must be device owner to perform. (to check ownership, see Device Info).

curl -X POST 'https://api.commadotai.com/v1/devices/02ec6bea180a4d36/del_user' \
-d '{"email": "mycommaenemy@gmail.com"}' \
-H 'Authorization: JWT {{token}}'

Response





{"success": 1}

Device driving statistics

GET /v1.1/devices/:dongle_id/stats

Returns aggregate driving statistics for a device

curl 'https://api.commadotai.com/v1.1/devices/02ec6bea180a4d36/stats' \
-H 'Authorization: JWT {{token}}'

Response

{
  "all": {
    "distance": 13026.936680094295,
    "minutes": 23809,
    "routes": 1349
  },
  "week": {
    "distance": 105.20453522778553,
    "minutes": 372,
    "routes": 28
  }
}

Response

JSON object with keys "all" and "week", each of which has this format:

Key Type Description
"distance" (float) Total miles driven in time period
"minutes" (integer) Total minutes driven in time period
"routes" (integer) Count of routes in time period

Device users

GET /v1/devices/:dongle_id/users

List users with access to a device

curl 'https://api.commadotai.com/v1/devices/02ec6bea180a4d36/users' \
-H 'Authorization: JWT {{token}}'

Response

[
  {
    "email": "deviceowner@comma.ai",
    "permission": "owner"
  },
  {
    "email": "devicereader@comma.ai",
    "permission": "read_access"
  }
]

Response

JSON array of user objects.

Key Type Description
email string User email
permission string Device permission, one of ("owner", "read_access")

Routes

Segments

GET /v1/devices/:dongle_id/segments

Returns time-sorted list of segments, each of which includes basic metadata derived from openpilot log.

curl 'https://api.commadotai.com/v1/devices/02ec6bea180a4d36/segments?from=1558508400000&to=1559718000000' \
-H 'Authorization: JWT {{token}}'

Parameters

from required

The lower bound on the start time of returned segments, in milliseconds since epoch.

to optional

The upper bound on end time of returned segments, in milliseconds since epoch. If omitted, defaults to now.

[
  {
    "canonical_name": "0375fdf7b1ce594d|2019-05-21--23-17-14--0",
    "canonical_route_name": "0375fdf7b1ce594d|2019-05-21--23-17-14",
    "number": 0,
    "git_remote": "git@github.com:commaai/one.git",
    "start_time_utc_millis": 1558505835614,
    "proc_dcamera": -1,
    "radar": false,
    "create_time": 1558505900,
    "hpgps": true,
    "end_time_utc_millis": 1558505895587,
    "end_lng": -117.0,
    "start_lng": -117.0,
    "passive": false,
    "proc_log": 40,
    "version": "0.5.12",
    "git_branch": "master",
    "end_lat": 32.0,
    "proc_camera": 40,
    "devicetype": 3,
    "start_lat": 32.0,
    "events_json": "[{\"data\": {\"pre_soft_disable\": false, \"end_offset_nanos\": 464369, \"alertSize\": 2, \"end_time\": \"466342645882391\", \"alertType\": \"startup\", \"end_route_offset_millis\": 15199, \"end_route_offset_nanos\": 464369, \"should_take_control\": false, \"end_offset_millis\": 15199, \"alertText1\": \"Be ready to take over at any time\", \"alertStatus\": 0, \"alertText2\": \"Always keep hands on wheel and eyes on road\"}, \"route_offset_nanos\": 817760, \"offset_millis\": 237, \"time\": \"466327684235782\", \"type\": \"alert\", \"offset_nanos\": 817760, \"route_offset_millis\": 237}]",
    "git_dirty": true,
    "url": "https://chffrprivate.blob.core.windows.net/chffrprivate3/v2/0375fdf7b1ce594d/aaaaaaa_2019-05-21--23-17-14/0",
    "length": 0.00179515,
    "dongle_id": "0375fdf7b1ce594d",
    "can": true,
    "git_commit": "8b7b90ce71eda504902f3a3c183ff5151bfac0d2"
  }
]

Response

JSON array of segment objects. Each segment has the following keys:

Key Type Description
"git_remote" string Git remote from openpilot log InitData
"start_time_utc_millis" integer Milliseconds since epoch of segment start time, from GPS
"number" integer Segment number
"proc_dcamera" integer Driver camera file status. See Segment File Status below
"radar" boolean True if segment contains radar tracks in CAN
"create_time" integer time of upload_url call for first file uploaded of segment
"hpgps" boolean True if segment has ublox packets
"end_time_utc_millis" integer Milliseconds since epoch of segment end time, from GPS
"end_lng" float Last longitude recorded in segment, from GPS
"start_lng" float First longitude recorded in segment, from GPS
"passive" boolean True if openpilot was running in passive mode. From openpilot log InitData
"canonical_name" string Segment name
"proc_log" Log file status. See Segment File Status below
"version" string Version string from openpilot log InitData
"git_branch" string Git branch from openpilot log InitData
"end_lat" float Last latitude recorded in segment from GPS
"proc_camera" Road camera file status. See Segment File Status below
"canonical_route_name" string Route name
"devicetype" integer 3 is EON
"start_lat" float First latitude recorded in segment from GPS
"git_dirty" boolean Git dirty flag from openpilot log InitData
"url" string Signed URL from which route.coords and jpegs can be downloaded (see Derived Data)
"length" float Sum of distances between GPS points, miles
"dongle_id" string Dongle ID
"can" boolean True if log has at least 1 can message
"git_commit" string Git commit from openpilot log InitData

Disengagement event

{
  "data": {
    "is_planned": false
  },
  "route_offset_nanos": 985946,
  "offset_millis": 45087,
  "time": "161093962680481",
  "type": "disengage",
  "offset_nanos": 942170,
  "route_offset_millis": 525093
}

"events_json" JSON array of event objects (is string encoded). Four types:

Engagement event

{
  "route_offset_nanos": 232202,
  "offset_millis": 12963,
  "time": "160941836926737",
  "type": "engage",
  "offset_nanos": 100204,
  "route_offset_millis": 372968
}

Alert event

{
  "data": {
    "pre_soft_disable": false,
    "end_offset_nanos": 824459,
    "alertSize": 2,
    "end_time": "156946181483417",
    "alertType": "steerSaturated",
    "end_route_offset_millis": 532376,
    "end_route_offset_nanos": 180003,
    "should_take_control": true,
    "end_offset_millis": 52400,
    "alertText1": "TAKE CONTROL",
    "alertStatus": 1,
    "alertText2": "Turn Exceeds Steering Limit"
  },
  "route_offset_nanos": 205578,
  "offset_millis": 47070,
  "time": "156940851508992",
  "type": "alert",
  "offset_nanos": 850034,
  "route_offset_millis": 527046
}

Steer override event

{
  "data": {
    "is_planned": false,
    "end_route_offset_millis": 877196,
    "end_time": "161446064800451",
    "end_offset_millis": 37255,
    "end_offset_nanos": 521861,
    "end_route_offset_nanos": 105916
  },
  "route_offset_nanos": 105243,
  "offset_millis": 26305,
  "time": "161435114799778",
  "type": "disengage_steer",
  "offset_nanos": 521188,
  "route_offset_millis": 866246
}

Note: The bits is_planned and pre_soft_disable are set in pipeline based on temporal correspondence with an alert for which we expect a disengagement.

Segment File Status

status code
upload_url_sent 0
received 10
enqueued 20
processing 30
processed 40

Route Info

GET /v1/route/:route_name/

Returns information about the provided route. Authenticated user must have ownership of or read access to device from which route was uploaded.

curl https://api.commadotai.com/v1/route/99c94dc769b5d96e\|2019-05-17--17-31-58/ \
-H 'Authorization: JWT {{token}}'

Response

{
  "git_remote": "git@github.com:commaai/openpilot.git",
  "start_lat": 32.0,
  "hpgps": true,
  "create_time": 1558654768,
  "maxdcamera": 2,
  "user_id": null,
  "end_lng": -117.0,
  "start_lng": -117.0,
  "passive": false,
  "platform": "HONDA CIVIC 2016 TOURING",
  "version": "0.5.12",
  "end_lat": 32.0,
  "git_branch": "devel",
  "maxcamera": 2,
  "proclog": 2,
  "maxlog": 2,
  "devicetype": 3,
  "proccamera": 2,
  "radar": true,
  "git_dirty": true,
  "init_logmonotime": 1932707747489,
  "url": "https://chffrprivate.blob.core.windows.net/chffrprivate3/v2/99c94dc769b5d96e/aaaaaaaaa_2019-05-17--17-31-58",
  "length": 0,
  "dongle_id": "99c94dc769b5d96e",
  "can": true,
  "git_commit": "39448abbb5bfc7ac1ae6424cd90b94a475ca12fa",
  "fullname": "99c94dc769b5d96e|2019-05-17--17-31-58"
}




Response

Key Type Description
"git_remote" string Git remote from openpilot log InitData
"radar" boolean True if any segment in route contains radar tracks in CAN
"create_time" integer time of upload_url call for first file uploaded of route
"hpgps" boolean True if any segment in route has ublox packets
"end_lng" float Last longitude recorded in route, from GPS
"start_lng" float First longitude recorded in route, from GPS
"passive" boolean True if openpilot was running in passive mode. From openpilot log InitData
"version" string Version string from openpilot log InitData
"git_branch" string Git branch from openpilot log InitData
"end_lat" float Last latitude recorded in route from GPS
"fullname" string Route name
"devicetype" integer 3 is EON
"start_lat" float First latitude recorded in route from GPS
"git_dirty" boolean Git dirty flag from openpilot log InitData
"init_logmonotime" integer Minimum logMonoTime from openpilot log
"url" string Signed URL from which route.coords and jpegs can be downloaded (see Derived Data)
"length" float Sum of distances between GPS points, miles
"dongle_id" string Dongle ID
"can" boolean True if log has at least 1 can message
"git_commit" string Git commit from openpilot log InitData
"user_id" string User ID of device owner
"maxlog" integer Maximum log segment number uploaded
"proclog" integer Maximum log segment number processed
"maxcamera" integer Maximum camera segment number uploaded
"proccamera" integer Maximum camera segment number processed
"maxdcamera" integer Maximum front camera segment number uploaded

Route Segments

GET /v1/route/:route_name/segments

Returns list of segments comprising a route. Authenticated user must have ownership of or read access to device from which route was uploaded.

curl https://api.commadotai.com/v1/route/0375fdf7b1ce594d\|2019-05-21--23-17-14/segments \
-H 'Authorization: JWT {{token}}'

Response

[
  {
    "can": true,
    "canonical_name": "0375fdf7b1ce594d|2019-05-21--23-17-14--5",
    "canonical_route_name": "0375fdf7b1ce594d|2019-05-21--23-17-14",
    "create_time": 1558506455,
    "devicetype": 3,
    "dongle_id": "0375fdf7b1ce594d",
    "end_lat": 32.7416,
    "end_lng": -117.18,
    "end_time_utc_millis": 1558506159491,
    "events_json": "[]",
    "git_branch": "master",
    "git_commit": "8b7b90ce71eda504902f3a3c183ff5151bfac0d2",
    "git_dirty": true,
    "git_remote": "git@github.com:commaai/openpilot.git",
    "hpgps": true,
    "length": 0.0267973,
    "number": 5,
    "passive": false,
    "proc_camera": 40,
    "proc_dcamera": -1,
    "proc_log": 40,
    "proc_qlog": null,
    "radar": false,
    "start_lat": 32.7415,
    "start_lng": -117.18,
    "start_time_utc_millis": 1558506135585,
    "url": "https://chffrprivate.blob.core.windows.net/chffrprivate3/v2/0375fdf7b1ce594d/39b636f2cde7d3e78e47d30c99fcdb62_2019-05-21--23-17-14/5",
    "version": "0.5.12"
  },
  {
    "can": true,
    "canonical_name": "0375fdf7b1ce594d|2019-05-21--23-17-14--4",
    "canonical_route_name": "0375fdf7b1ce594d|2019-05-21--23-17-14",
    "create_time": 1558506337,
    "devicetype": 3,
    "dongle_id": "0375fdf7b1ce594d",
    "end_lat": 32.7414,
    "end_lng": -117.18,
    "end_time_utc_millis": 1558506135580,
    "events_json": "[]",
    "git_branch": "master",
    "git_commit": "8b7b90ce71eda504902f3a3c183ff5151bfac0d2",
    "git_dirty": true,
    "git_remote": "git@github.com:commaai/openpilot.git",
    "hpgps": true,
    "length": 0.895458,
    "number": 4,
    "passive": false,
    "proc_camera": 40,
    "proc_dcamera": -1,
    "proc_log": 40,
    "proc_qlog": null,
    "radar": false,
    "start_lat": 32.7309,
    "start_lng": -117.171,
    "start_time_utc_millis": 1558506075584,
    "url": "https://chffrprivate.blob.core.windows.net/chffrprivate3/v2/0375fdf7b1ce594d/39b636f2cde7d3e78e47d30c99fcdb62_2019-05-21--23-17-14/4",
    "version": "0.5.12"
  },
  {
    "can": true,
    "canonical_name": "0375fdf7b1ce594d|2019-05-21--23-17-14--3",
    "canonical_route_name": "0375fdf7b1ce594d|2019-05-21--23-17-14",
    "create_time": 1558506214,
    "devicetype": 3,
    "dongle_id": "0375fdf7b1ce594d",
    "end_lat": 32.7304,
    "end_lng": -117.17,
    "end_time_utc_millis": 1558506075581,
    "events_json": "[]",
    "git_branch": "master",
    "git_commit": "8b7b90ce71eda504902f3a3c183ff5151bfac0d2",
    "git_dirty": true,
    "git_remote": "git@github.com:commaai/openpilot.git",
    "hpgps": true,
    "length": 0.51377,
    "number": 3,
    "passive": false,
    "proc_camera": 40,
    "proc_dcamera": -1,
    "proc_log": 40,
    "proc_qlog": null,
    "radar": false,
    "start_lat": 32.7258,
    "start_lng": -117.167,
    "start_time_utc_millis": 1558506015585,
    "url": "https://chffrprivate.blob.core.windows.net/chffrprivate3/v2/0375fdf7b1ce594d/39b636f2cde7d3e78e47d30c99fcdb62_2019-05-21--23-17-14/3",
    "version": "0.5.12"
  },
  {
    "can": true,
    "canonical_name": "0375fdf7b1ce594d|2019-05-21--23-17-14--2",
    "canonical_route_name": "0375fdf7b1ce594d|2019-05-21--23-17-14",
    "create_time": 1558506095,
    "devicetype": 3,
    "dongle_id": "0375fdf7b1ce594d",
    "end_lat": 32.7258,
    "end_lng": -117.167,
    "end_time_utc_millis": 1558506015584,
    "events_json": "[]",
    "git_branch": "master",
    "git_commit": "8b7b90ce71eda504902f3a3c183ff5151bfac0d2",
    "git_dirty": true,
    "git_remote": "git@github.com:commaai/openpilot.git",
    "hpgps": true,
    "length": 0.275832,
    "number": 2,
    "passive": false,
    "proc_camera": 40,
    "proc_dcamera": -1,
    "proc_log": 40,
    "proc_qlog": null,
    "radar": false,
    "start_lat": 32.7218,
    "start_lng": -117.166,
    "start_time_utc_millis": 1558505955274,
    "url": "https://chffrprivate.blob.core.windows.net/chffrprivate3/v2/0375fdf7b1ce594d/39b636f2cde7d3e78e47d30c99fcdb62_2019-05-21--23-17-14/2",
    "version": "0.5.12"
  },
  {
    "can": true,
    "canonical_name": "0375fdf7b1ce594d|2019-05-21--23-17-14--1",
    "canonical_route_name": "0375fdf7b1ce594d|2019-05-21--23-17-14",
    "create_time": 1558505980,
    "devicetype": 3,
    "dongle_id": "0375fdf7b1ce594d",
    "end_lat": 32.7217,
    "end_lng": -117.166,
    "end_time_utc_millis": 1558505955571,
    "events_json": "[]",
    "git_branch": "master",
    "git_commit": "8b7b90ce71eda504902f3a3c183ff5151bfac0d2",
    "git_dirty": true,
    "git_remote": "git@github.com:commaai/openpilot.git",
    "hpgps": true,
    "length": 0.0933126,
    "number": 1,
    "passive": false,
    "proc_camera": 40,
    "proc_dcamera": -1,
    "proc_log": 40,
    "proc_qlog": null,
    "radar": false,
    "start_lat": 32.7202,
    "start_lng": -117.167,
    "start_time_utc_millis": 1558505895585,
    "url": "https://chffrprivate.blob.core.windows.net/chffrprivate3/v2/0375fdf7b1ce594d/39b636f2cde7d3e78e47d30c99fcdb62_2019-05-21--23-17-14/1",
    "version": "0.5.12"
  },
  {
    "can": true,
    "canonical_name": "0375fdf7b1ce594d|2019-05-21--23-17-14--0",
    "canonical_route_name": "0375fdf7b1ce594d|2019-05-21--23-17-14",
    "create_time": 1558505900,
    "devicetype": 3,
    "dongle_id": "0375fdf7b1ce594d",
    "end_lat": 32.7202,
    "end_lng": -117.167,
    "end_time_utc_millis": 1558505895587,
    "events_json": "[{\"data\": {\"pre_soft_disable\": false, \"end_offset_nanos\": 464369, \"alertSize\": 2, \"end_time\": \"466342645882391\", \"alertType\": \"startup\", \"end_route_offset_millis\": 15199, \"end_route_offset_nanos\": 464369, \"should_take_control\": false, \"end_offset_millis\": 15199, \"alertText1\": \"Be ready to take over at any time\", \"alertStatus\": 0, \"alertText2\": \"Always keep hands on wheel and eyes on road\"}, \"route_offset_nanos\": 817760, \"offset_millis\": 237, \"time\": \"466327684235782\", \"type\": \"alert\", \"offset_nanos\": 817760, \"route_offset_millis\": 237}]",
    "git_branch": "master",
    "git_commit": "8b7b90ce71eda504902f3a3c183ff5151bfac0d2",
    "git_dirty": true,
    "git_remote": "git@github.com:commaai/openpilot.git",
    "hpgps": true,
    "length": 0.00179515,
    "number": 0,
    "passive": false,
    "proc_camera": 40,
    "proc_dcamera": -1,
    "proc_log": 40,
    "proc_qlog": null,
    "radar": false,
    "start_lat": 32.7231,
    "start_lng": -117.169,
    "start_time_utc_millis": 1558505835614,
    "url": "https://chffrprivate.blob.core.windows.net/chffrprivate3/v2/0375fdf7b1ce594d/39b636f2cde7d3e78e47d30c99fcdb62_2019-05-21--23-17-14/0",
    "version": "0.5.12"
  }
]





Response

Returns JSON array of segments. See Segments

Route Manifest

GET /v1/route/:route_name/manifest

Lists files uploaded for a route.

curl https://api.commadotai.com/v1/route/cce908f7eb8db67d\|2019-10-12--10-41-14/manifest \
-H 'Authorization: JWT {{token}}'

Response

[
  {
    "file": "qlog.bz2",
    "key": "cce908f7eb8db67d/2019-10-12--10-41-14/0/qlog.bz2",
    "last_modified": "2019-10-12 17:42:25",
    "segment": "cce908f7eb8db67d|2019-10-12--10-41-14--0",
    "size": 321044
  },
  {
    "file": "qlog.bz2",
    "key": "cce908f7eb8db67d/2019-10-12--10-41-14/1/qlog.bz2",
    "last_modified": "2019-10-12 17:43:51",
    "segment": "cce908f7eb8db67d|2019-10-12--10-41-14--1",
    "size": 299785
  },
  {
    "file": "dcamera.hevc",
    "key": "cce908f7eb8db67d/2019-10-12--10-41-14/0/dcamera.hevc",
    "last_modified": "2019-10-12 18:23:49",
    "segment": "cce908f7eb8db67d|2019-10-12--10-41-14--0",
    "size": 17338425
  },
  {
    "file": "fcamera.hevc",
    "key": "cce908f7eb8db67d/2019-10-12--10-41-14/0/fcamera.hevc",
    "last_modified": "2019-10-12 17:53:25",
    "segment": "cce908f7eb8db67d|2019-10-12--10-41-14--0",
    "size": 34631930
  },
  {
    "file": "rlog.bz2",
    "key": "cce908f7eb8db67d/2019-10-12--10-41-14/0/rlog.bz2",
    "last_modified": "2019-10-12 17:43:45",
    "segment": "cce908f7eb8db67d|2019-10-12--10-41-14--0",
    "size": 4733423
  },
  {
    "file": "dcamera.hevc",
    "key": "cce908f7eb8db67d/2019-10-12--10-41-14/1/dcamera.hevc",
    "last_modified": "2019-10-12 18:39:39",
    "segment": "cce908f7eb8db67d|2019-10-12--10-41-14--1",
    "size": 17281817
  },
  {
    "file": "fcamera.hevc",
    "key": "cce908f7eb8db67d/2019-10-12--10-41-14/1/fcamera.hevc",
    "last_modified": "2019-10-12 18:34:48",
    "segment": "cce908f7eb8db67d|2019-10-12--10-41-14--1",
    "size": 34561050
  },
  {
    "file": "rlog.bz2",
    "key": "cce908f7eb8db67d/2019-10-12--10-41-14/1/rlog.bz2",
    "last_modified": "2019-10-12 18:25:08",
    "segment": "cce908f7eb8db67d|2019-10-12--10-41-14--1",
    "size": 4747911
  }
]





Response

JSON array of file objects

Key Type Description
"file" (string) File name
"key" (string) File key
"last_modified" (string) File upload time, UTC
"segment" (string) Name of segment in which file was produced
"size" (integer) Number of bytes in file

Raw driving data

Files

GET /v1/route/:route_name/files

Retrieve uploaded files for a route. Calls to this API are rate limited to 5 per minute.

curl https://api.commadotai.com/v1/route/99c94dc769b5d96e\|2019-05-17--17-31-58/files \
-H 'Authorization: JWT {{token}}'

Response





{
  "cameras": [
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/0/fcamera.hevc?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--0--fcamera.hevc&sr=b&sp=r&sv=2018-03-28&sig=WHR7QdvxYs%2BhsM5b1inMCpgAErknsmPqW0G0KNk%2B8BQ%3D&se=2019-06-06T02%3A23%3A16Z",
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/1/fcamera.hevc?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--1--fcamera.hevc&sr=b&sp=r&sv=2018-03-28&sig=b/q0wRkyUfdkOnxhedZ3AfEVV6dNBIqWJmDKJ2iMYXw%3D&se=2019-06-06T02%3A23%3A16Z",
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/2/fcamera.hevc?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--2--fcamera.hevc&sr=b&sp=r&sv=2018-03-28&sig=3jTlj3zehVAkr4iPg7c9kzUhD6VTNioPws0tmNlvWmg%3D&se=2019-06-06T02%3A23%3A16Z"
  ],
  "dcameras": [
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/0/dcamera.hevc?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--0--dcamera.hevc&sr=b&sp=r&sv=2018-03-28&sig=L4Apvh4NZbzz8FEE2sHC0Y6ShUiKRR99jsmBUuGOC4c%3D&se=2019-06-06T02%3A23%3A16Z",
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/1/dcamera.hevc?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--1--dcamera.hevc&sr=b&sp=r&sv=2018-03-28&sig=03ayVwQ0VBIj9cfgOwj892GK2IZFq9U/HH%2BltEF9gB0%3D&se=2019-06-06T02%3A23%3A16Z",
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/2/dcamera.hevc?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--2--dcamera.hevc&sr=b&sp=r&sv=2018-03-28&sig=r9Df0Yt72IFNNXU8FT85gkkXebw%2Bv2uOc0DXvyuu%2B%2B4%3D&se=2019-06-06T02%3A23%3A16Z"
  ],
  "logs": [
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/0/rlog.bz2?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--0--rlog.bz2&sr=b&sp=r&sv=2018-03-28&sig=Yxe2QiC88aoNRwxHQsVuunRWa6MaJDIZitktOY43PfA%3D&se=2019-06-06T02%3A23%3A16Z",
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/1/rlog.bz2?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--1--rlog.bz2&sr=b&sp=r&sv=2018-03-28&sig=xRGalraKsT9PWjtyL2SCr7IqnzvxVwm0ihgvha1iNLk%3D&se=2019-06-06T02%3A23%3A16Z",
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/2/rlog.bz2?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--2--rlog.bz2&sr=b&sp=r&sv=2018-03-28&sig=60%2BJSFBn8vveU0nc3Sld1iUIiAiJBRa6PBhFl4deWWg%3D&se=2019-06-06T02%3A23%3A16Z"
  ],
  "qlogs": [
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/0/rlog.bz2?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--0--qlog.bz2&sr=b&sp=r&sv=2018-03-28&sig=Yxe2QiC88aoNRwxHQsVuunRWa6MaJDIZitktOY43PfA%3D&se=2019-06-06T02%3A23%3A16Z",
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/1/rlog.bz2?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--1--qlog.bz2&sr=b&sp=r&sv=2018-03-28&sig=xRGalraKsT9PWjtyL2SCr7IqnzvxVwm0ihgvha1iNLk%3D&se=2019-06-06T02%3A23%3A16Z",
    "https://commadata2.blob.core.windows.net/commadata2/99c94dc769b5d96e/2019-05-17--17-31-58/2/rlog.bz2?rscd=attachment%3B%20filename%3D99c94dc769b5d96e_2019-05-17--17-31-58--2--qlog.bz2&sr=b&sp=r&sv=2018-03-28&sig=60%2BJSFBn8vveU0nc3Sld1iUIiAiJBRa6PBhFl4deWWg%3D&se=2019-06-06T02%3A23%3A16Z"
  ],
  "qcameras": []
}

Response "cameras": Array of signed URLs to fcamera.hevc "dcameras": Array of signed URLs to dcamera.hevc "logs": Array of signed URLs to rlog.bz2 "qlogs": Array of signed URLs to qlog.bz2 "qcameras": Array of signed URLs to qcamera.ts

URLs are valid for 1 hour. All arrays are sorted by segment number ascending.

Video Stream

Base URL: https://video.comma.ai

Rear Camera Stream

GET /hls/:dongle_id/:route_signature/index.m3u8

Returns rear camera HLS stream index of MPEG-TS fragments

route_signature is the 3rd from last path component of a url from the segments endpoint.

curl https://video.comma.ai/hls/cb38263377b873ee/78392b99580c5920227cc5b43dff8a70_2017-06-12--18-51-47/index.m3u8

Response

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD

#EXTINF:3.049958,
8_61.ts?v=2
#EXTINF:3.049955,
69_61.ts?v=2
#EXTINF:3.049955,
130_61.ts?v=2
#EXTINF:3.049958,
191_61.ts?v=2
#EXTINF:3.049970,
252_61.ts?v=2
#EXTINF:3.049955,
313_61.ts?v=2
#EXTINF:3.050007,
374_61.ts?v=2
#EXTINF:3.049913,
435_61.ts?v=2
#EXTINF:3.049942,
496_61.ts?v=2
#EXTINF:3.049964,
557_61.ts?v=2
#EXTINF:3.049955,
618_61.ts?v=2

Front Camera Stream

GET /hls/:dongle_id/:route_signature/dcamera/index.m3u8

Returns front camera HLS stream index of MPEG-TS fragments

route_signature is the 3rd from last path component of a url from the segments endpoint.

curl https://video.comma.ai/hls/cb38263377b873ee/78392b99580c5920227cc5b43dff8a70_2017-06-12--18-51-47/dcamera/index.m3u8

Response

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD

#EXTINF:3.049958,
8_61.ts?v=2
#EXTINF:3.049955,
69_61.ts?v=2
#EXTINF:3.049955,
130_61.ts?v=2
#EXTINF:3.049958,
191_61.ts?v=2
#EXTINF:3.049970,
252_61.ts?v=2
#EXTINF:3.049955,
313_61.ts?v=2
#EXTINF:3.050007,
374_61.ts?v=2
#EXTINF:3.049913,
435_61.ts?v=2
#EXTINF:3.049942,
496_61.ts?v=2
#EXTINF:3.049964,
557_61.ts?v=2
#EXTINF:3.049955,
618_61.ts?v=2

Device Bootlogs

GET /v1/devices/:dongle_id/bootlogs

Returns most recent bootlogs uploaded from a device.

curl 'https://api.commadotai.com/v1/devices/02ec6bea180a4d36/bootlogs' \
-H 'Authorization: JWT {{token}}'

Response

[
  "https://commadata2.blob.core.windows.net/commadata2/02ec6bea180a4d36/2019-10-14--09-47-45/0/bootlog.bz2?se=2019-10-16T17%3A52%3A03Z&sp=r&sv=2018-03-28&sr=b&rscd=attachment%3B%20filename%3D02ec6bea180a4d36_2019-10-14--09-47-45--0--bootlog.bz2&sig=sig/4%3D"
]

Response

JSON array of URLs of bootlog files. Files are available at each URL for one hour after time of API call.

Derived Data

GPS Path

After openpilot uploads a log, a JSON array of GPS coordinates interpolated at 1hz is exposed at a signed URL in the cloud. As segments are uploaded, route.coords will be appended to atomically.

To access the GPS path, first obtain a segment url key from the /v1/devices/:dongle_id/segments response. Chop off the last path component, which represents the segment number. Append route.coords. For example:

https://chffrprivate.blob.core.windows.net/chffrprivate3-permanent/v2/cb38263377b873ee/78392b99580c5920227cc5b43dff8a70_2017-06-12--18-51-47/route.coords

Video Frames (every 5s)

JPEGs are extracted every 5s from road camera video and are exposed at a signed URL in the cloud.

To access the JPEGs, first obtain a segment url key from the /v1/devices/:dongle_id/segments response. Chop off the last path component, which represents the segment number. Append secN.jpg where N is the 0-indexed number of seconds since start of the route. For example:

https://chffrprivate.blob.core.windows.net/chffrprivate3-permanent/v2/cb38263377b873ee/78392b99580c5920227cc5b43dff8a70_2017-06-12--18-51-47/sec400.jpg

Vehicles

Vehicle by ID

GET /v1/vehicles/:vehicle_id

Retrieve vehicle metadata by ID.

curl https://api.commadotai.com/v1/vehicles/3322 \
-H 'Authorization: JWT {{token}}'

Response





{
  "id": 3322,
  "fuel_vehicle_id": 27301,
  "make": "Honda",
  "model": "Accord",
  "op_support": 1,
  "photo_url": "https://i.fuelapi.com/3aa269fc5f58457390d04285416561b7/27301/1/17/stills_0640_png/MY2018/12415/12415_st0640_046.png",
  "trim": "LX - Sedan",
  "year": 2018
}

Response

Key Type Description
"id" (integer) Vehicle ID
"fuel_vehicle_id" (integer) Vehicle ID from our media source, FuelAPI.com
"make" (string) Vehicle make
"model" (string) Vehicle model
"year" (integer) Vehicle year
"trim" (string) Vehicle trim
"op_support" (integer) Represents openpilot support. 0=Unknown 1=candidate 2=unsupported 3=community supported 4=lateral only 5=lateral and longitudinal
"photo_url" (string) URL to photo from FuelAPI.com. You may not use this URL in your own applications. If you wish to display a vehicle photo on your application, sign up for FuelAPI.com and use the fuel_vehicle_id value with your personal API key.

List Vehicle Makes

GET /v1/vehicles/makes/

List available vehicle makes and years.

curl https://api.commadotai.com/v1/vehicles/makes/ \
-H 'Authorization: JWT {{token}}'

Response





[
  {
    "make": "Acura",
    "years": [
      2019,
      2018,
      2017,
      2016,
      2015,
      2014,
      2013,
      2012,
      2011,
      2010,
      2009,
      2008
    ]
  },
  ...
]

Response

JSON array of vehicle objects with keys:

Key Type Description
"make" (string) Vehicle make name
"years" (array of integers) Model years available for make

List vehicles by make

GET /v1/vehicles/makes/:make_name

Returns JSON array of vehicle metadata

curl https://api.commadotai.com/v1/vehicles/makes/Honda \
-H 'Authorization: JWT {{token}}'

Response





[
  {
    "fuel_vehicle_id": 26164,
    "id": 3295,
    "make": "Honda",
    "model": "Accord",
    "op_support": 0,
    "photo_url": "https://i.fuelapi.com/3aa269fc5f58457390d04285416561b7/26164/1/17/stills_0640_png/MY2016/10782/10782_st0640_046.png",
    "trim": "LX - Sedan",
    "year": 2017
  },
  {
    "fuel_vehicle_id": 26164,
    "id": 3296,
    "make": "Honda",
    "model": "Accord",
    "op_support": 1,
    "photo_url": "https://i.fuelapi.com/3aa269fc5f58457390d04285416561b7/26164/1/17/stills_0640_png/MY2016/10782/10782_st0640_046.png",
    "trim": "LX w/Honda Sensing - Sedan",
    "year": 2017
  },
  ...
]

Response

JSON array of vehicle objects. See Vehicle by ID

openpilot

openpilot auth

POST https://api.commadotai.com/v2/pilotauth/

Query parameters

imei: Device IMEI

serial: Device Serial

public_key: 2048-bit RSA Public Key

register_token: JWT token signed by your private key containing payload: {"register": True}

curl -X POST 'https://api.commadotai.com/v2/pilotauth/?imei=000000000000000&serial=aaaaaaaa&public_key=ssh-rsa%20AAAAB3NzaC1yc2EAAAADAQABAAABAQDeEAshPfzEDsSg8yZnidU8%2BGZSw%2BjS21vcoDlnrnI/3SQ8njvY0o6hHIt9Soxf%2BvnNF9amZ51tysblNIhkF9igwqXKNaEzIX2MKJSwp0rNdJSoLM8SSYBNlfyFUTsoakW2p6FQ9E01RgspFR8xBT91lrJ6eKKKmYP/P24mF6KfgdZ57%2BvTehmrj5MJi14lN18q8KM8nyppNvB5t0ijMeBq64x0TZig3o7rQxzzX0uMemNWZ3fXADL7lJUcyNO8Vv70%2BAddP9Ek8zgna7msUbzwbV1O1eUb9t3jlKHTN7zhfTXrxzwoNETHMn0569rZFmqfUf%2BHBEKLgUck1QMZIkRX%20root%40localhost&register_token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJyZWdpc3RlciI6dHJ1ZSwiZXhwIjoxNTU5ODUzNTA3fQ.h5RMQ4ThPDy3Otadq0pcmnTROdXDklfxj6ItLqzxc8sNzioMa9qBeBRA22H75N11ucAOwxaF6ckO5AGDcDf5VwMwGbdibaVnTfUHP4mofz6usD-92lJbzQ1k0YwebPftBAoL4epRfS52Z1JVVLxNwCW9Mb9rexnc_tn2S7JQzHJUb1BLGSGengC1MtReXvIIjDK9FP-KAI9ZluvzIXnNtGvVfzJiVPwMQzmY4xRUewVXUJPPs6tv1oz26UW4Kd9aYhQo4KJAIUTAvY0gA_SYrcZIzC1pFcHY50Qot2HqW4HdJcoaXWqaWakbz4xUpswbiaQi1bdZoVa8b5Ht9r8p_g'

Response

{
  "dongle_id": "02c45f73a2e5c6e9",
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6ImZvbyIsImlhdCI6MTU2MDc1NDUzMywibmJmIjoxNTYwNzU0NTMzLCJleHAiOjE1OTIyOTA1MzN9.V34lp0Nq0EZMw7b5I8xnZaMvIbS2eisUsrFbXg4itaY"
}

Response

Key Type Description
"dongle_id" (string) Dongle ID
"access_token" (string) JWT token (see Authentication)

Athena WebSocket

Listen for inbound JSON-RPC requests. This is used by openpilot's athenad.py.

Base URL: wss://athena.comma.ai:8765

/:dongle_id

curl --include \
     --no-buffer \
     --header "Connection: Upgrade" \
     --header "Upgrade: websocket" \
     --header "Host: athena.comma.ai:8765" \
     --header "Origin: https://athena.comma.ai:8765" \
     --cookie "jwt={{device_token}}" \
     https://athena.comma.ai:8765/02c45f73a2e5c6e9

Upload URL

GET /v1.3/:dongle_id/upload_url/

Request a URL to which an openpilot file can be uploaded via PUT request. This endpoint only accepts tokens signed with a device private key (openpilot 0.6.3 and newer.)

Parameters

path: segment directory and name of file to upload from openpilot data directory. for example, 2019-06-06--11-30-31--9/fcamera.hevc

curl https://api.commadotai.com/v1.3/ccfab3437bea5257/upload_url/?path=2019-06-06--11-30-31--9/fcamera.hevc \
-H 'Authorization: JWT jwt_signed_with_device_private_key'

Response

{
  "url": "https://commaincoming.blob.core.windows.net/commaincoming/239e82a1d3c855f2/2019-06-06--11-30-31/9/fcamera.hevc?sr=b&sp=cw&sig=cMCrZt5fje7SDXlKcOIjHgA0wEVAol71FL6ac08Q2Iw%3D&sv=2018-03-28&se=2019-06-13T18%3A43%3A01Z"
}

Response "url" (string): URL to which a PUT request can be sent with file contents

Athena

Athena HTTP

Send JSON-RPC requests to the active websocket client for a given device identified by Dongle ID.

Base URL: https://athena.comma.ai

POST /:dongle_id



Request body

{
  "method": "getMessage",
  "params": {"service": "thermal", "timeout": 5000},
  "jsonrpc": "2.0",
  "id": 0
}

JSON-RPC payload with keys:

Key Type Description
"method" (string) json-rpc method - see openpilot athenad.py for supported methods
"params" (object) method-specific params. For getMessage:
"params.service" (string) service name (see openpilot service_list.yaml)
"params.timeout" (integer) milliseconds client should wait for message from service
"jsonrpc" (string) constant, "2.0"
"id" (integer) constant, 0





curl https://athena.comma.ai/02c45f73a2e5c6e9 \
-d '{"method":"getMessage","params":{"service":"thermal","timeout":5000},"jsonrpc":"2.0","id":0}' \
-H 'Authorization: JWT {{token}}'

Response

{
  "jsonrpc": "2.0",
  "result": {
    "thermal": {
      "batteryStatus": "Discharging",
      "freeSpace": 0.9546145796775818,
      "bat": 28700,
      "usbOnline": false,
      "batteryCurrent": 330808,
      "startedTs": 0,
      "mem": 333,
      "chargingError": false,
      "cpu2": 333,
      "cpu3": 333,
      "cpu0": 343,
      "cpu1": 323,
      "fanSpeed": 0,
      "batteryVoltage": 4200414,
      "chargingDisabled": false,
      "started": false,
      "batteryPercent": 93,
      "gpu": 309,
      "thermalStatus": "green"
    },
    "valid": true,
    "logMonoTime": 107226885676532
  },
  "id": "ba0daa7a-a208-410f-8f11-1e1e6f29edeb"
}

Response

JSON-RPC response object with keys:

Key Type Description
"jsonrpc" string "2.0", constant
"result" object method-specific result. For getMessage, it's a zmq message encoded as dictionary. see openpilot log.capnp
"id" string request ID

Annotations

My Annotations

GET /v1/me/annotations/

List annotations contributed by authenticated user

Parameters

from required

The lower bound on the contribution time of returned annotations, in milliseconds since epoch.

to optional

The upper bound on contribution time of returned annotations, in milliseconds since epoch. If omitted, defaults to now.

curl 'https://api.commadotai.com/v1/me/annotations/?from=1528316175000&to=1559852238000' \
-H 'Authorization: JWT {{token}}'

Response

[
  {
    "user_id": "104654435692089730759",
    "start_time_utc_millis": 1556659764896,
    "data": {
      "reason": "different-way"
    },
    "offset_nanos_part": 701747,
    "end_time_utc_millis": 1556659764896,
    "create_time": 1556751588,
    "canonical_segment_name": "b0c9d2329ad1606b|2019-04-30--14-26-19--3",
    "segment_offset_nanos": 4294701747,
    "dongle_id": "b0c9d2329ad1606b",
    "type": "disengage_steer",
    "id": "999e703e679f16045524c0f3d62b22db",
    "offset_millis": 4294
  },
  ...
]

Response

JSON array of annotation objects. See Annotation by ID

Device Annotations

GET /v1/devices/:dongle_id/annotations/

List annotations contributed to drives from a device that authenticated user has ownership of or read access to.

Parameters

from required

The lower bound on the contribution time of returned annotations, in milliseconds since epoch.

to optional

The upper bound on contribution time of returned annotations, in milliseconds since epoch. If omitted, defaults to now.

curl 'https://api.commadotai.com/v1/devices/b0c9d2329ad1606b/annotations/?from=1528316175000&to=1559852238000' \
-H 'Authorization: JWT {{token}}'

Response

[
  {
    "user_id": "104654435692089730759",
    "start_time_utc_millis": 1556659764896,
    "data": {
      "reason": "different-way"
    },
    "offset_nanos_part": 701747,
    "end_time_utc_millis": 1556659764896,
    "create_time": 1556751588,
    "canonical_segment_name": "b0c9d2329ad1606b|2019-04-30--14-26-19--3",
    "segment_offset_nanos": 4294701747,
    "dongle_id": "b0c9d2329ad1606b",
    "type": "disengage_steer",
    "id": "999e703e679f16045524c0f3d62b22db",
    "offset_millis": 4294
  },
  ...
]

Response

JSON array of annotation objects. See Annotation by ID

Annotation by ID

GET /v1/annotations/:annotation_id

Returns annotation object. Authenticated user must have contributed the annotation.

curl https://api.commadotai.com/v1/annotations/999e703e679f16045524c0f3d62b22db \
-H 'Authorization: JWT {{token}}'

Response

{
  "user_id": "104654435692089730759",
  "start_time_utc_millis": 1556659764896,
  "data": {
    "reason": "different-way"
  },
  "offset_nanos_part": 701747,
  "end_time_utc_millis": 1556659764896,
  "create_time": 1556751588,
  "canonical_segment_name": "b0c9d2329ad1606b|2019-04-30--14-26-19--3",
  "segment_offset_nanos": 4294701747,
  "dongle_id": "b0c9d2329ad1606b",
  "type": "disengage_steer",
  "id": "999e703e679f16045524c0f3d62b22db",
  "offset_millis": 4294
}

Response

JSON object with annotation information.

Key Type Description
"user_id" (string) Oauth ID of user who contributed annotation
"start_time_utc_millis" (integer) Milliseconds since epoch of annotation event start time
"end_time_utc_millis" (integer) Milliseconds since epoch of annotation event end time. Often is the same as "start_time_utc_millis," but exists to allow for annotating time windows.
"segment_offset_nanos" (integer) nanoseconds since start of segment of annotation start time
"offset_millis" (integer) milliseconds since start of segment of annotation start time
"offset_nanos_part" (integer) nanoseconds since offset_millis of annotation start time
"dongle_id" (string) Dongle ID of device that uploaded the annotated segment
"type" (string) one of ("disengage", "disengage_steer")
"id" (string) annotation ID
"data" (object) Annotation attributes
"data.reason" (string) one of:
- "arbitrary"
- "different-way"
- "lanes"
- "too-slow"
- "exit"
- "stop-light"
- "stop-sign"
- "other-desire"
- "danger"
- "sharp-turn"
- "bad-lanes"
- "bad-lead-car"
- "other-safety"
"data.comment" (string, optional) free-form commentary

Create Annotation

POST /v1/annotations/new

Create new annotation.

Headers

Content-Type: application/json

Request body

{
  "canonical_segment_name": "fd10b9a107bb2e49|2018-05-23--16-31-54--6",
  "offset_millis": 1000,
  "offset_nanos_part": 50,
  "start_time_utc_millis": 0,
  "end_time_utc_millis": 0,
  "type": "some_annotation_type",
  "data": {
    "optional_extra_keys": "associated_with_type"
  }
}

Request body

Key Type Description
"start_time_utc_millis" (integer) Milliseconds since epoch of annotation event start time
"end_time_utc_millis" (integer) Milliseconds since epoch of annotation event end time. Often is the same as "start_time_utc_millis," but exists to allow for annotating time windows.
"data" (object) Annotation attributes
"data.reason" (string) one of:
- "arbitrary"
- "different-way"
- "lanes"
- "too-slow"
- "exit"
- "stop-light"
- "stop-sign"
- "other-desire"
- "danger"
- "sharp-turn"
- "bad-lanes"
- "bad-lead-car"
- "other-safety"
"data.comment" (string, optional) free-form commentary
"offset_millis" (integer) milliseconds since start of segment of annotation start time
"offset_nanos_part" (integer) nanoseconds since offset_millis of annotation start time
"type" (string) one of ("disengage", "disengage_steer")
curl -X POST https://api.commadotai.com/v1/annotations/new \
-d '{"canonical_segment_name":"fd10b9a107bb2e49|2018-05-23--16-31-54--6","offset_millis":1000,"offset_nanos_part":50,"start_time_utc_millis":0,"end_time_utc_millis":0,"type":"disengage","data":{"reason":"too-slow"}}' \
-H 'Content-Type: application/json' \
-H 'Authorization: JWT {{token}}'

Response

{
  "user_id": "104654435692089730759",
  "start_time_utc_millis": 0,
  "data": {
    "reason": "too-slow"
  },
  "offset_millis": 1000,
  "offset_nanos_part": 50,
  "end_time_utc_millis": 0,
  "create_time": 1556751588,
  "canonical_segment_name": "fd10b9a107bb2e49|2018-05-23--16-31-54--6",
  "segment_offset_nanos": 1000000050,
  "dongle_id": "b0c9d2329ad1606b",
  "type": "disengage",
  "id": "999e703e679f16045524c0f3d62b22db"
}

Response

Identical to Annotation by ID

Delete annotation

DELETE /v1/annotations/:annotation_id

Delete an annotation by ID. Authenticated user must have contributed the annotation.

curl -X DELETE https://api.commadotai.com/v1/annotations/999e703e679f16045524c0f3d62b22db \
-H 'Authorization: JWT {{token}}'

Response

{"success": 1}

Update annotation

PATCH /v1/annotations/:annotation_id

Update "data" object. Authenticated user must have contributed the annotation.

Headers

Content-Type: application/json


Request body

{
  "data": {
    "reason": "lanes",
    "comment": "Lanes misidentified"
  }
}

Request body

JSON-encoded object with keys:

curl -X PATCH https://api.commadotai.com/v1/annotations/999e703e679f16045524c0f3d62b22db \
-d '{"data": {"reason": "lanes", "comment": "Lanes misidentified"}}' \
-H 'Content-Type: application/json' \
-H 'Authorization: JWT {{token}}'

Response

{
  "user_id": "104654435692089730759",
  "start_time_utc_millis": 0,
  "data": {
    "reason": "lanes"
  },
  "offset_millis": 1000,
  "offset_nanos_part": 50,
  "end_time_utc_millis": 0,
  "create_time": 1556751588,
  "canonical_segment_name": "fd10b9a107bb2e49|2018-05-23--16-31-54--6",
  "segment_offset_nanos": 1000000050,
  "dongle_id": "b0c9d2329ad1606b",
  "type": "disengage",
  "id": "999e703e679f16045524c0f3d62b22db"
}

Response

JSON-encoded annotation object with updated data object. See Annotation by ID

Leaderboard

List top leaders

GET /v2/leaderboard/

Returns overall and last-week comma point leaders.

curl https://api.commadotai.com/v2/leaderboard/ \
-H 'Authorization: JWT {{token}}'
{
  "all": [
    {
      "joinDate": "2016-04-11",
      "points": 49673,
      "username": "lordricky",
      "weekly": 2338
    },
    {
      "joinDate": "2016-03-25",
      "points": 2291,
      "username": "tom",
      "weekly": 0
    },
    ...
  ],
  "weekly": [
    {
      "joinDate": "2016-04-11",
      "points": 49673,
      "username": "lordricky",
      "weekly": 2338
    },
    {
      "joinDate": "2016-03-25",
      "points": 2291,
      "username": "tom",
      "weekly": 0
    },
    ...
  ]
}




Response

JSON object with keys:

Key Type Description
"all" (array) Leaderboard entry objects sorted by points key. Structure of each:
"joinDate" (string) Join date formatted as ISO8601 string
"points" (integer) All-time comma points total
"username" (string) Username
"weekly" (integer) comma points earned in last 7 days
"weekly" (array) Same structure as all, but sorted by weekly points.