pebble/devsite/source/_guides/pebble-timeline/timeline-public.md

343 lines
9.3 KiB
Markdown
Raw Permalink Normal View History

---
# 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" }
```