Used by players to report how long a track was played and the time since it was last played. This notifies the cloud queue server via an HTTP POST when a track finishes playing. The payload includes the total playback duration, including any scrubbing and seeking within the track, as well as a signal whether the track ended due to a skip operation or not. Players only send reports when a track has played for more than one second. See Add reporting for details on how to use this API for SMAPI reporting.
Request
The request header contains the access token in the authorization header. The request body contains the the tracks played, sent in the items
parameter. The parameters in the table below are in the request body.
Parameter | Type | Description |
---|---|---|
items |
array | A list of tracks reported by the player, including an identifier, URL, time played, and time since played (see below). |
Item attributes (v2.3)
For v2.3, the items
array includes the additional attributes below.
Attribute | Type | Description |
---|---|---|
error |
object | Indicates the “type” of error and associated “status” that prevented the speaker from initiating or interrupting playback. See SMAPI error objects below for details. |
reportId |
string | This is a stable UUID in the canonical format that you may use to correlate periodic and final reports for a single logical track playback. Unlike the id field, this identifier changes on each logical playback of the track queue item. For example, you can use this attribute to differentiate reports for id 0 when Sonos plays a different item in between, such as when a user skips back to item id 0. |
Examples (v2.3)
Final event with a reportId
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "items":[ { "reportId":"0e5614b9-fcc7-4eec-b087-1892b7e64fa6", "id":"this_is_the_cloud_queue_item_id", "mediaUrl":"http://media.host.example.com/path/12345.mp3", "queueVersion":"xyz", "contextVersion":"abc", "type":"final", "positionMillis":500, "positionMillisAtSegmentStart":0, "durationPlayedMillis":500, "timeSincePlaybackMillis":1250 } ] } |
Item attributes (v2.2)
For v2.2, the items
array includes the additional attributes below.
Attribute | Type | Description |
---|---|---|
actions |
array | Replaces skip from v2.0. (Optional) Indicates the user action, which may contain: “play”, “seek”, “skip”, “skipBack”, or “pause”.
The player uses this for “skip” or “pause”. If “skip” is present for a report type of “final”, it indicates that the track ended as the result of a skip. If “pause” is present for a final or update report, it indicates that the track was paused by the user. |
Examples (v2.2)
Update event when sendPlaybackActions
reporting option is set to true
and the user pauses playback:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{ "items":[ { "id":"this_is_the_cloud_queue_item_id", "mediaUrl":"http://media.host.example.com/path/12345.mp3", "queueVersion":"xyz", "type":"update", "positionMillis":4211, "positionMillisAtSegmentStart":3461, "actions":[ { "pause":[ { "positionMillis":4211 } ] } ], "durationPlayedMillis":4000, "timeSincePlaybackMillis":5250 }, "..." ] } |
Final event when sendPlaybackActions
reporting option is set to true
and the user skips a track:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{ "items":[ { "id":"this_is_the_cloud_queue_item_id", "mediaUrl":"http://media.host.example.com/path/12345.mp3", "queueVersion":"xyz", "contextVersion":"abc", "type":"final", "positionMillis":500, "positionMillisAtSegmentStart":0, "actions":[ { "skip":[ { "positionMillis":500 } ] } ], "durationPlayedMillis":500, "timeSincePlaybackMillis":1250 } ] } |
Item attributes (v2.1)
For v2.1, the items
array includes the updated or additional attributes below.
Attribute | Type | Description |
---|---|---|
contextVersion |
string | The player provides this parameter to indicate the context state at the time of reporting. Server implementations are free to ignore this information. For items played in the Sonos queue this element is omitted. |
containerId |
string | For SMAPI content only. This is equivalent to the contextId , the parent container of the enqueued object. For example, the playlist, radio, or album containing the item. For single enqueued tracks, the containerId is the same as the track ID. |
id |
string | Updated in 2.1. The window item ID for cloud queues. For items played in the Sonos queue this element is omitted. |
objectId |
string | Present when playing a SMAPI object. It contains the SMAPI object ID. Omitted when using Cloud Queues without SMAPI IDs. |
mediaUrl |
string | Updated in 2.1. URL of the item played. When using SMAPI objects, this is the internal Sonos URI, not the dereferenced URI. |
Examples (v2.1)
SMAPI track from an enqueued album:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{ "items":[ { "containerId":"al:47", "durationPlayedMillis":28031, "mediaUrl":"x-sonosapi-hls-static:tr%3a541?sid=253&flags=32800&sn=46", "objectId":"tr:541", "positionMillis":28031, "positionMillisAtSegmentStart":0, "timeSincePlaybackMillis":28218, "type":"final" } ] } |
SMAPI track playing on cloud queue:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "items":[ { "contextVersion":"3080d8b6ee2573c4f8af0153d76c067d", "durationPlayedMillis":28031, "id":"this_is_the_cloud_queue_item_id", "mediaUrl":"x-sonos-http:tr%3a345.mp3?sid=253&flags=0&sn=46", "objectId":"tr:345", "positionMillis":28031, "positionMillisAtSegmentStart":0, "queueVersion":"a074b6bee4694a73e55f1fb56f4570f5", "timeSincePlaybackMillis":28218, "type":"final" } ] } |
Item attributes (v2.0)
For v2.0, the items
array has the attributes described below.
Attribute | Type | Description |
---|---|---|
id |
string | The queue ID of the item that played. |
mediaUrl |
string | URL of the item that played. |
queueVersion |
string | The version of the last cloud queue item window fetched by the player. |
durationPlayedMillis |
number | The total duration of playback, in milliseconds. This is cumulative including any scrub or seek operations within the track during a single playback, so this value may be greater than the duration of the track. |
timeSincePlaybackMillis |
number | The time in milliseconds since this track began playback. This value gives the you a reference for when playback started. This value reports the delta between when playback began and when the POST /timePlayed request was posted. This can be different from durationPlayedMillis due to pausing and resuming. |
positionMillis |
number | The current playhead position at the time of the report. |
positionMillisAtSegmentStart |
number | The playhead position at the start of the current segment. For example, this could contain the position where the user last paused. |
type |
string | The type of report. This can be final or update . You can specify the interval for players to send update reports in your GET /context responses. Players will always post final reports once after each track finishes playing or is skipped.
Note that you shouldn’t use these reports to track playback actions because players don’t post them immediately. |
skip |
object | (Optional). If this is present for a report type of final , it indicates that the track ended as the result of a skip. This includes a reportId string to identify the skip report. |
Examples (v2.0)
Without a skip:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "items": [ { "id": "this_is_the_cloud_queue_item_id", "mediaUrl": "http://media.host.example.com/path/12345.mp3", "queueVersion" : "xyz", "type": "final", "durationPlayedMillis": 293000, "timeSincePlaybackMillis": 298000, "positionMillis": 293000, "positionMillisAtSegmentStart": 22300 }, ... ] } |
With a skip:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "items": [ { "id": "this_is_the_cloud_queue_item_id", "mediaUrl": "http://media.host.example.com/path/12345.mp3", "queueVersion": "xyz", "type": "final", "skip": {}, "durationPlayedMillis": 293000, "timeSincePlaybackMillis": 298000, "positionMillis": 293000, "positionMillisAtSegmentStart": 22300 }, ... ] } |
Update:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
{ "items":[ { "id":"this_is_the_cloud_queue_item_id", "mediaUrl":"http://media.host.example.com/path/12345.mp3", "queueVersion":"xyz", "type":"update", "durationPlayedMillis":31914, "timeSincePlaybackMillis":33742, "positionMillis":45000, "positionMillisAtSegmentStart":14000 }, "..." ] } |
Item attributes (v1.0)
The items
array has the attributes described below.
Attribute | Type | Description |
---|---|---|
itemId |
string | The queue ID of the track that played. |
trackUrl |
string | The URL of the track that played. |
durationPlayedMillis |
number | Total duration of playback, in milliseconds. This is cumulative including any scrub or seek operations within the track during a single playback, so this value can be greater than the duration of the track. |
timeSincePlaybackMillis |
number | The time, in milliseconds, since this item began playback. This value gives the music service provider a reference for when playback started. This value reports the delta between when playback began and the /timePlayed message was posted. This can be different from durationPlayedMillis due to pausing and resuming. |
Example (v1.0)
One or more arrays of items:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
{ “items”: [ { "kind": "musicqueue#itemPlayedData", "itemId": "Track12345", "trackUrl": "http://example.com/track12345.mp3", "durationPlayedMillis": 240000, "timeSincePlaybackMillis": 360000 } , { "kind": "musicqueue#itemPlayedData", "itemId": "Track12346", "trackUrl": "http://example.com/track12346.mp3", "durationPlayedMillis": 180000, "timeSincePlaybackMillis": 600000 } ] } |
Response
At the minimum, your cloud queue response to the player should be an HTTP 204 No Content
success status response code or an error code. See Error Handling for a list of error response codes. The response should not contain any data in the payload body.
Response (v2.1)
As of Cloud Queue v2.1, your server may return a JSON context object in the payload body. Return an HTTP 200 OK
success status response code if you return data. If you return 200 with unexpected JSON, Sonos disables periodic reporting for the remainder of the track.
For example, you may want to update report options without waiting for the player to notice a context version change. This improves latency.
If you want to return a response body, you must return the full context object, similar to what your server would send in response to GET /context. This is due to a strict parser which requires the full object. However, Sonos ignores everything except for the periodicIntervalMillis
value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
{ catalogItemId: { type: 'default', id: 'root' }, version: '72416b71498e4984b17e631de49fa35d', skipEnforcement: { configuration: {}, version: 1, remaining: 6, lastSkip: 1590084593496, skipsAllowed: true, maxSkips: 5, restoreSkipsAfterSec: 20 }, reportPolicyVersion: 0, reports: { periodicIntervalMillis: 20000 }, policies: { version: 17, policies: { canSkip: true, limitedSkips: false, canSkipBack: true, canSeek: true, canRepeat: true, canRepeatOne: true, canCrossfade: true, canShuffle: true, pauseAtEndOfQueue: true, showNNextTracks: 3, showNPreviousTracks: 0, notifyUserIntent: false, pauseTtlSec: 0, playTtlSec: 0, pauseOnDuck: null, canResume: false } }, policyVersion: 17, skipEnforcementVersion: 1, container: { version: 1, type: 'station', name: 'Bruce Springsteen Radio', imageUrl: 'http://images.example.com/station_art.jpg', id: { serviceId: '255', objectId: 'sta12345', accountId: 'user981' }, service: { id: '255', name: 'ACME MUSIC' }, tags: [] }, containerVersion: 1, success: 'success' } |
SMAPI error objects
These errors give you information about playback errors while starting playback and after playback has begun. These include:
- Connectivity, or readability errors, including read/write timeouts, DNS errors, etc.
- HTTP transport errors, such as 404, 500, etc.
- Decoding errors. For example, when Sonos detects badly encoded files or files that Sonos framers were not able to handle.
- Buffering errors. For example, anything that creates audio interrupts or causes audio to stop all together.
Field | Type | Description |
---|---|---|
type |
string | The type of error being reported. Values include: http, transport, or playback. |
status |
string | Status code pertinent to error type . See the table of values below. |
Errors for “http” type
Valid HTTP Status codes.
Examples
Dereferenced URI returned in getMediaURI
is no longer accessible due to security restrictions. For example, an expired URI.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
POST /v2.3/report/timePlayed HTTP/1.1 CONNECTION: close ACCEPT: */* ACCEPT-ENCODING: gzip HOST: 192.168.0.10:8223 USER-AGENT: Linux UPnP/1.0 Sonos/46.2-56030-ci-517-content-ux-414254 (ZPS1) AUTHORIZATION: 1533680812459_7 CONTENT-TYPE: application/json CONTENT-LENGTH: 251 X-Sonos-Playback-Id: RINCON_B8E937C0011801400:3876374424 X-Sonos-Device-Id: Sonos_MTM_0fQXuhqKvFlHJJoBrRhH1e_38a8f8e0 X-Sonos-CorrId: 6f14bb40-b3a5-45ae-be86-de3a7a41cbb1 X-MockSMAPI-ApiKey: F118580B-8A55-4A3E-85BE-3D69191AC35F { "items": [ { "containerId": "al:54", "durationPlayedMillis": 0, "error": { "type": "http", "status" : "403" }, "mediaUrl": "x-sonos-http:tr%3a582.mp4?sid=255&flags=32800&sn=13", "objectId": "tr:582", "positionMillis": 0, "positionMillisAtSegmentStart": 0, "timeSincePlaybackMillis": 0, "type": "final" } ] } |
Errors for “transport” type
These include connectivity, framers, SMAPI and other channel source errors that were not a result of an HTTP error.
Code | Description |
---|---|
ERROR_OCCURRED |
Unknown error. |
ERROR_LOST_CONNECTION |
Unexpected network error. |
ERROR_CANT_REACH_SERVER |
Network timeout. |
ERROR_UNSUPPORTED_FORMAT |
Sonos can not play this content. |
ERROR_CORRUPT_FILE |
Detected a known content type but could not play it. |
ERROR_TOO_MANY_USERS |
SMAPI server reported too many users. |
ERROR_CANT_RESOLVE_NAME |
DNS error. |
ERROR_SONOS_NO_ACCOUNT |
Account was removed from the Sonos household. |
ERROR_SONOS_BAD_ACCOUNT |
SMAPI server reported the user has no access to the content. |
ERROR_SONOS_STREAM_LIMIT |
SMAPI server detected multiple stream limit reached for a particular account. |
ERROR_ACCESS_DENIED_EXPLICIT |
Unable to play track because parental controls are enabled. |
ERROR_SONOS_TOKEN_EXPIRED |
SMAPI OAuth token is expired, and user must re-authorize the account. |
ERROR_SONOSAPI_X |
Custom SMAPI fault, where X = [0, 999]. |
Example
Custom SOAP Fault with error code “9” returned from SMAPI server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
{ "items": [ { "containerId": "tr:25", "durationPlayedMillis": 0, "error": { "type": "transport", "status": "ERROR_SONOSAPI_9" }, "mediaUrl": "x-sonos-http:tr%3a25.mp3?sid=255&flags=32&sn=13", "objectId": "tr:25", "positionMillis": 0, "positionMillisAtSegmentStart": 0, "timeSincePlaybackMillis": 0, "type": "final" } ] } |
Errors for “playback” type
These include Channel Sink errors. Currently this only includes ERROR_LSE
, Large Sync Errors.