The Canonical ID is returned in the response when you send a message from your server to the google gcm server.
https://developer.android.com/google/gcm/http.html#response
Interpretation of the response to success
When the JSON request is successful (HTTP status code 200), the body response contains a JSON object with the following fields:
Field Description multicast_id Unique identifier (number) identifying the multicast message. success The number of processed messages without errors. Error The number of messages that could not be processed. canonical_ids The number of results containing the canonical registration number. See Advanced Topics for a more in-depth discussion of this subject. topic. results An array of objects representing the status of the processed messages. The objects are listed in the same order as the request (i.e., for each registration identifier in the request, its result is equal to those listed in the same index in the response), and they can have these fields: message_id: A string representing the message when it was successfully processed. registration_id: if set, it means that GCM processed the message, but it has a different canonical registration identifier for this device, so the sender must replace the identifiers with future requests (otherwise they may be rejected). This field is never set if this is a request error. error: A string describing the error that occurred while processing the message for this recipient. The possible values are the same as in the above table, plus "Unavailable" (which means that the GCM servers are busy and cannot process the message for this particular recipient so that it can be repeated). If the failure value and canonical_ids is 0, there is no need to parse the rest of the response.
Update
Below is the detailed information on Canonical ID. Basically, if somehow the device identifier reg stops synchronizing with what Google thinks it should be, then when your server sends a request with a missing synchronization identifier, the gcm server will include a response in it, the correct identifier used in the future .
Think about it, how it works; your server should have kept the reg identifier when the device is registered with gcm. Your server sends a request to gcm with this id, gcm uses this identifier to send a message to your device. GCM cannot use the reg identifier on your device without telling the server about it. If your server just sent the wrong reg id. Instead, gcm will tell the server that the reg identifier it uses for a particular device is bad, your server can then send a message to the device to update its stored reg identifier to what it should be, and then the device can override the change in identifiers REG. The information below implies that there is some time limit, because for too long a “bad” identifier can still be used to send messages. I think the assumption is that it should be long enough so that your server can change the device ID (via gcm message using a "bad" id)
Canonical identifiers
On the server side, as long as the application behaves well, everything should work fine. However, if an application error causes multiple registrations for the same device, it can be difficult to reconcile the state and you may get duplicate messages.
GCM provides a facility called “canonical registration identifiers” to easily recover from these situations. The canonical registration identifier is defined as the identifier of the last registration requested by your application. This is the identifier that the server should use when sending messages to the device.
If you later try to send a message using a different registration identifier, GCM will process the request as usual, but it will contain the canonical registration identifier in the registration_id field of the response. Be sure to replace the registration identifier stored on your server with this canonical identifier, as in the end the identifier you use will stop working.