---
title: "Register this device for push notifications"
method: POST
path: "/v1/devices"
tags: ["devices"]
---

# Register this device for push notifications

`POST /v1/devices`

## Request

- Base URL: `https://api.getmyhotels.com`
- URL: `https://api.getmyhotels.com/v1/devices`
- Auth: HTTP bearer

Runs `push.register`. Idempotent per token — the app calls this on every launch, which is what keeps `lastSeenAt` meaningful. A bearer token is honored but NOT required, and sending one is what claims a guest's device row into their account: the row is upserted on the token, so the first launch after signing in re-points an existing guest registration at the user. There is no separate claim call.

`platform` selects the push service and, with it, how `token` is validated. It defaults to `ios` for the clients that shipped before it existed.

**iOS (APNs).** Send the token as lowercase hex with no separators — `Data.description` prints `<a1b2 c3d4 …>`, which is not that, and a non-hex token is rejected here rather than becoming a row that can never receive a push. `environment` picks the APNs host and the two are not interchangeable. `bundleId` is the APNs topic, stored per device so an extension cannot inherit the app's.

**Android (FCM).** Send the registration token exactly as `FirebaseMessaging.getToken()` returned it — base64url with a colon, longer than an APNs token and never hex. `environment` is always `production`: FCM has one endpoint and one credential for every build. `bundleId` is the applicationId (`com.gmh.mobile`, or `com.gmh.mobile.dev` for a debug build); FCM routes on the token alone, so it is a record of which build registered rather than an address.

## Request body

- object
  - `token` string, required
  - `platform` 'ios' | 'android'
  - `environment` 'production' | 'development'
  - `bundleId` string, required
  - `locale` string, nullable

## Response `200`

Success

- unknown

## Other responses

- `400`: Request validation failed or the router rejected the input
- `426`: Reported X-GMH-App-Version is below the supported minimum — the app must update
- `500`: Unexpected server error (opaque; details stay in logs)

---

[API](https://skmtc.dev/getmyhotels/apis/getmyhotels-rest-api.md) · [All operations](https://skmtc.dev/getmyhotels/apis/getmyhotels-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getmyhotels/apis/getmyhotels-rest-api/revisions/cba24a9c13f0?raw)
