mirror of
https://github.com/google/pebble.git
synced 2025-03-20 19:01:21 +00:00
343 lines
9.3 KiB
Markdown
343 lines
9.3 KiB
Markdown
|
---
|
||
|
# Copyright 2025 Google LLC
|
||
|
#
|
||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
# you may not use this file except in compliance with the License.
|
||
|
# You may obtain a copy of the License at
|
||
|
#
|
||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
#
|
||
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
# See the License for the specific language governing permissions and
|
||
|
# limitations under the License.
|
||
|
|
||
|
title: Public Web API
|
||
|
description: |
|
||
|
How to push Pebble timeline data to an app's users using the public web API.
|
||
|
guide_group: pebble-timeline
|
||
|
order: 3
|
||
|
related_examples:
|
||
|
- title: Hello Timeline
|
||
|
url: https://github.com/pebble-examples/hello-timeline
|
||
|
- title: Timeline TV Tracker
|
||
|
url: https://github.com/pebble-examples/timeline-tv-tracker
|
||
|
- title: Timeline Push Pin
|
||
|
url: https://github.com/pebble-examples/timeline-push-pin
|
||
|
---
|
||
|
|
||
|
While users can register subscriptions and receive data from the timeline using
|
||
|
the PebbleKit JS subscriptions API
|
||
|
(detailed in {% guide_link pebble-timeline/timeline-js %}), app developers can
|
||
|
use the public timeline web API to provide that data by pushing pins. Developers
|
||
|
will need to create a simple web server to enable them to process and send the
|
||
|
data they want to display in the timeline. Each pin represents a specific event
|
||
|
in the past or the future, and will be shown on the watch once pushed to the
|
||
|
public timeline web API and automatically synchronized with the watch via the
|
||
|
Pebble mobile applications.
|
||
|
|
||
|
The Pebble SDK emulator supports the timeline and automatically synchronizes
|
||
|
every 30 seconds.
|
||
|
|
||
|
|
||
|
## Pushing Pins
|
||
|
|
||
|
Developers can push data to the timeline using their own backend servers. Pins
|
||
|
are created and updated using HTTPS requests to the Pebble timeline web API.
|
||
|
|
||
|
> Pins pushed to the Pebble timeline web API may take **up to** 15 minutes to
|
||
|
> appear on a user's watch. Although most pins can arrive faster than this, we
|
||
|
> recommend developers do not design apps that rely on near-realtime updating of
|
||
|
> pins.
|
||
|
|
||
|
|
||
|
### Create a Pin
|
||
|
|
||
|
To create a pin, send a `PUT` request to the following URL scheme, where `ID` is
|
||
|
the `id` of the pin object. For example 'reservation-1395203':
|
||
|
|
||
|
```text
|
||
|
PUT https://timeline-api.getpebble.com/v1/user/pins/ID
|
||
|
```
|
||
|
|
||
|
Use the following headers, where `X-User-Token` is the user's
|
||
|
timeline token (read
|
||
|
{% guide_link pebble-timeline/timeline-js#get-a-timeline-token "Get a Timeline Token" %}
|
||
|
to learn how to get a token):
|
||
|
|
||
|
```text
|
||
|
Content-Type: application/json
|
||
|
X-User-Token: a70b23d3820e9ee640aeb590fdf03a56
|
||
|
```
|
||
|
|
||
|
Include the JSON object as the request body from a file such as `pin.json`. A
|
||
|
sample of an object is shown below:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"id": "reservation-1395203",
|
||
|
"time": "2014-03-07T08:01:10.229Z",
|
||
|
"layout": {
|
||
|
"shortTitle": "Dinner at La Fondue",
|
||
|
...
|
||
|
},
|
||
|
...
|
||
|
}
|
||
|
```
|
||
|
|
||
|
|
||
|
#### Curl Example
|
||
|
|
||
|
```bash
|
||
|
$ curl -X PUT https://timeline-api.getpebble.com/v1/user/pins/reservation-1395203 \
|
||
|
--header "Content-Type: application/json" \
|
||
|
--header "X-User-Token: a70b23d3820e9ee640aeb590fdf03a56" \
|
||
|
-d @pin.json
|
||
|
OK
|
||
|
```
|
||
|
|
||
|
|
||
|
### Update a Pin
|
||
|
|
||
|
To update a pin, send a `PUT` request with a new JSON object with the **same
|
||
|
`id`**.
|
||
|
|
||
|
```text
|
||
|
PUT https://timeline-api.getpebble.com/v1/user/pins/reservation-1395203
|
||
|
|
||
|
```
|
||
|
|
||
|
Remember to include the user token in the headers.
|
||
|
|
||
|
```text
|
||
|
X-User-Token: a70b23d3820e9ee640aeb590fdf03a56
|
||
|
```
|
||
|
|
||
|
When an update to an existing pin is issued, it replaces the original
|
||
|
pin entirely, so all fields (including those that have not changed) should be
|
||
|
included. The example below shows an event updated with a new `time`:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"id": "reservation-1395203",
|
||
|
"time": "2014-03-07T09:01:10.229Z",
|
||
|
"layout": {
|
||
|
"shortTitle": "Dinner at La Fondue",
|
||
|
...
|
||
|
},
|
||
|
...
|
||
|
}
|
||
|
```
|
||
|
|
||
|
|
||
|
#### Curl Example
|
||
|
|
||
|
```bash
|
||
|
$ curl -X PUT https://timeline-api.getpebble.com/v1/user/pins/reservation-1395203 \
|
||
|
--header "Content-Type: application/json" \
|
||
|
--header "X-User-Token: a70b23d3820e9ee640aeb590fdf03a56" \
|
||
|
-d @pin.json
|
||
|
OK
|
||
|
```
|
||
|
|
||
|
|
||
|
### Delete a Pin
|
||
|
|
||
|
Delete a pin by issuing a HTTP `DELETE` request.
|
||
|
|
||
|
```text
|
||
|
DELETE https://timeline-api.getpebble.com/v1/user/pins/reservation-1395203
|
||
|
```
|
||
|
|
||
|
Remember to include the user token in the headers.
|
||
|
|
||
|
```text
|
||
|
X-User-Token: a70b23d3820e9ee640aeb590fdf03a56
|
||
|
```
|
||
|
|
||
|
This pin will then be removed from that timeline on the user's watch.
|
||
|
In some cases it may be preferred to simply update a pin with a cancelled
|
||
|
event's details so that it can remain visible and useful to the user.
|
||
|
|
||
|
|
||
|
#### Curl Example
|
||
|
|
||
|
```bash
|
||
|
$ curl -X DELETE https://timeline-api.getpebble.com/v1/user/pins/reservation-1395203 \
|
||
|
--header "Content-Type: application/json" \
|
||
|
--header "X-User-Token: a70b23d3820e9ee640aeb590fdf03a56"
|
||
|
OK
|
||
|
```
|
||
|
|
||
|
|
||
|
## Shared Pins
|
||
|
|
||
|
### Create a Shared Pin
|
||
|
|
||
|
It is possible to send a pin (and updates) to multiple users at once by
|
||
|
modifying the `PUT` header to include `X-Pin-Topics` (the topics a user must be
|
||
|
subscribed to in order to receive this pin) and `X-API-Key` (issued by the
|
||
|
[Developer Portal](https://dev-portal.getpebble.com/)). In this case, the URL is
|
||
|
also modified:
|
||
|
|
||
|
```text
|
||
|
PUT /v1/shared/pins/giants-game-1
|
||
|
```
|
||
|
|
||
|
The new headers:
|
||
|
|
||
|
```text
|
||
|
Content-Type: application/json
|
||
|
X-API-Key: fbbd2e4c5a8e1dbef2b00b97bf83bdc9
|
||
|
X-Pin-Topics: giants,redsox,baseball
|
||
|
```
|
||
|
|
||
|
The pin body remains the same:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"id": "giants-game-1",
|
||
|
"time": "2014-03-07T10:01:10.229Z",
|
||
|
"layout": {
|
||
|
"title": "Giants vs Red Sox: 5-3",
|
||
|
...
|
||
|
},
|
||
|
...
|
||
|
}
|
||
|
```
|
||
|
|
||
|
|
||
|
#### Curl Example
|
||
|
|
||
|
```bash
|
||
|
$ curl -X PUT https://timeline-api.getpebble.com/v1/shared/pins/giants-game-1 \
|
||
|
--header "Content-Type: application/json" \
|
||
|
--header "X-API-Key: fbbd2e4c5a8e1dbef2b00b97bf83bdc9" \
|
||
|
--header "X-Pin-Topics: giants,redsox,baseball" \
|
||
|
-d @pin.json
|
||
|
OK
|
||
|
```
|
||
|
|
||
|
|
||
|
### Delete a Shared Pin
|
||
|
|
||
|
Similar to deleting a user pin, shared pins can be deleted by issuing a `DELETE`
|
||
|
request:
|
||
|
|
||
|
```text
|
||
|
DELETE /v1/shared/pins/giants-game-1
|
||
|
```
|
||
|
|
||
|
As with creating a shared pin, the API key must also be provided in the request
|
||
|
headers:
|
||
|
|
||
|
```text
|
||
|
X-API-Key: fbbd2e4c5a8e1dbef2b00b97bf83bdc9
|
||
|
```
|
||
|
|
||
|
|
||
|
#### Curl Example
|
||
|
|
||
|
```bash
|
||
|
$ curl -X DELETE https://timeline-api.getpebble.com/v1/shared/pins/giants-game-1 \
|
||
|
--header "Content-Type: application/json" \
|
||
|
--header "X-API-Key: fbbd2e4c5a8e1dbef2b00b97bf83bdc9" \
|
||
|
OK
|
||
|
```
|
||
|
|
||
|
|
||
|
## Listing Topic Subscriptions
|
||
|
|
||
|
Developers can also query the public web API for a given user's currently
|
||
|
subscribed pin topics with a `GET` request:
|
||
|
|
||
|
```text
|
||
|
GET /v1/user/subscriptions
|
||
|
```
|
||
|
|
||
|
This requires the user's timeline token:
|
||
|
|
||
|
```text
|
||
|
X-User-Token: a70b23d3820e9ee640aeb590fdf03a56
|
||
|
```
|
||
|
|
||
|
|
||
|
#### Curl Example
|
||
|
|
||
|
```bash
|
||
|
$ curl -X GET https://timeline-api.getpebble.com/v1/user/subscriptions \
|
||
|
--header "X-User-Token: a70b23d3820e9ee640aeb590fdf03a56" \
|
||
|
```
|
||
|
|
||
|
The response will be a JSON object containing an array of topics the user is
|
||
|
currently subscribed to for that app:
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"topics": [
|
||
|
"topic1",
|
||
|
"topic2"
|
||
|
]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
|
||
|
## Pin Time Limitations
|
||
|
|
||
|
The `time` property on a pin pushed to the public API must not be more than two
|
||
|
days in the past, or a year in the future. The same condition applies to the
|
||
|
`time` associated with a pin's reminders and notifications.
|
||
|
|
||
|
Any pins that fall outside these conditions may be rejected by the web API. In
|
||
|
addition, the actual range of events shown on the watch may be different under
|
||
|
some conditions.
|
||
|
|
||
|
For shared pins, the date and time of an event will vary depending on the user's
|
||
|
timezone.
|
||
|
|
||
|
|
||
|
## Error Handling
|
||
|
|
||
|
In the event of an error pushing a pin, the public timeline API will return one
|
||
|
of the following responses.
|
||
|
|
||
|
| HTTP Status | Response Body | Description |
|
||
|
|-------------|---------------|-------------|
|
||
|
| 200 | None | Success. |
|
||
|
| 400 | `{ "errorCode": "INVALID_JSON" }` | The pin object submitted was invalid. |
|
||
|
| 403 | `{ "errorCode": "INVALID_API_KEY" }` | The API key submitted was invalid. |
|
||
|
| 410 | `{ "errorCode": "INVALID_USER_TOKEN" }` | The user token has been invalidated, or does not exist. All further updates with this user token will fail. You should not send further updates for this user token. A user token can become invalidated when a user uninstalls an app for example. |
|
||
|
| 429 | `{ "errorCode": "RATE_LIMIT_EXCEEDED" }` | Server is sending updates too quickly, and has been rate limited (see [*Rate Limiting*](#rate-limiting) below). |
|
||
|
| 503 | `{ "errorCode": "SERVICE_UNAVAILABLE" }` | Could not save pin due to a temporary server error. |
|
||
|
|
||
|
|
||
|
## Rate Limiting
|
||
|
|
||
|
For requests using API Keys, developers can make up to 5000 requests per minute.
|
||
|
For requests using User Tokens, up to 300 requests every 15 minutes can be made.
|
||
|
Check the returned HTTP headers of any API request to see the current rate limit
|
||
|
status:
|
||
|
|
||
|
```text
|
||
|
$ curl -i https://timeline-api.getpebble.com/v1/user/pins/reservation-1395203
|
||
|
|
||
|
HTTP/1.1 429 OK
|
||
|
date: Wed, 13 May 2015 21:36:58 GMT
|
||
|
x-ratelimit-percent: 100
|
||
|
retry-after: 43
|
||
|
```
|
||
|
|
||
|
The headers contain information about the current rate limit status:
|
||
|
|
||
|
| Header Name | Description |
|
||
|
|-------------|-------------|
|
||
|
| `x-ratelimit-percent` | The percentage of the rate limit currently utilized. |
|
||
|
| `retry-after` | When `x-ratelimit-percent` has reached `100`, this header will be set to the number of seconds after which the rate limit will reset. |
|
||
|
|
||
|
When the rate limit is exceeded, the response body also reports the error:
|
||
|
|
||
|
```text
|
||
|
{ "errorCode":"RATE_LIMIT_EXCEEDED" }
|
||
|
```
|