GetMyHotels Account API
The account API from GetMyHotels — 5 operation(s) for account.
The account API from GetMyHotels — 5 operation(s) for account.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/getmyhotels-com:getmyhotels-com-account-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: GetMyHotels REST Account API
version: 1.0.0
description: REST surface for the native GetMyHotels apps. Every route is a thin transport over the shared tRPC routers — inputs are validated with the same Zod schemas the web client uses, and responses are returned verbatim. Authentication uses Better Auth bearer session tokens issued by the /api/auth/* endpoints (not part of this spec). Native clients send X-GMH-App-Version and X-GMH-Platform on every request; versions below the configured floor receive a typed 426 UpgradeRequiredError.
servers:
- url: https://api.getmyhotels.com
description: Production API
tags:
- name: Account
paths:
/v1/account/set-password:
post:
tags:
- Account
summary: Legacy password setup route; email verification required
description: 'Retained for older clients. Returns PRECONDITION_FAILED: a signed-in session alone cannot establish a password. Use POST /api/auth/request-password-reset and complete the emailed link through POST /api/auth/reset-password to set the first password or replace a forgotten one. Password reset revokes existing sessions.'
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
newPassword:
type: string
minLength: 6
maxLength: 128
required:
- newPassword
responses:
'200':
description: Success
content:
application/json:
schema:
description: Verbatim JSON output of the `auth.setPassword` tRPC procedure. Response shapes are intentionally not modeled in this spec; the native client types them by hand.
'400':
description: Request validation failed or the router rejected the input
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'401':
description: Missing or invalid bearer session token
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'426':
description: Reported X-GMH-App-Version is below the supported minimum — the app must update
content:
application/json:
schema:
$ref: '#/components/schemas/UpgradeRequiredError'
'500':
description: Unexpected server error (opaque; details stay in logs)
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
operationId: postV1AccountSetPassword
x-operation-id-source: derived
/v1/account/delete:
post:
tags:
- Account
summary: Delete the signed-in user's own account
description: 'Runs `user.deleteMyAccount`. IRREVERSIBLE. Anonymizes the Better Auth `user` row (name/email/image blanked to `deleted-@anon.local`) and BANS it so sign-in is impossible, hard-deletes the owned personal-data tables (profile, addresses, saved payment methods, travel companions, recently viewed, saved searches, price alerts and watches, notification preferences, notifications, wishlists), revokes every active session, then writes a `gdpr_request` deletion record and a `user.self_deleted` audit entry. Bookings, reviews, support tickets and the audit log are deliberately KEPT for legal and accounting retention — they now point at the anonymized row. Requires `{ "confirm": "DELETE MY ACCOUNT" }` verbatim; anything else is a 400. Refuses non-`customer` roles with 403 FORBIDDEN — staff and admin accounts go through admin offboarding so access can be handed over first.'
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
confirm:
type: string
enum:
- DELETE MY ACCOUNT
required:
- confirm
responses:
'200':
description: Success
content:
application/json:
schema:
description: Verbatim JSON output of the `user.deleteMyAccount` tRPC procedure. Response shapes are intentionally not modeled in this spec; the native client types them by hand.
'400':
description: Request validation failed or the router rejected the input
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'401':
description: Missing or invalid bearer session token
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'426':
description: Reported X-GMH-App-Version is below the supported minimum — the app must update
content:
application/json:
schema:
$ref: '#/components/schemas/UpgradeRequiredError'
'500':
description: Unexpected server error (opaque; details stay in logs)
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
operationId: postV1AccountDelete
x-operation-id-source: derived
/v1/account/profile:
get:
tags:
- Account
summary: Read the signed-in user's profile
description: 'Runs `user.getProfile`. Returns `{ user, profile }`: the Better Auth `user` row (id, name, email, emailVerified, image, role, timestamps) plus the `user_profile` row, which is `null` until the customer has saved something. The bearer session payload carries the user half only, so this is the sole way to read the stored phone, date of birth, nationality, preferred currency/language/country and address that the settings screen and the checkout guest defaults render. Read `user.name` from here rather than from the session: this is our copy, so it is populated once `PATCH /v1/account/profile` has run even when the identity provider never gave us one.'
security:
- bearerAuth: []
responses:
'200':
description: Success
content:
application/json:
schema:
description: Verbatim JSON output of the `user.getProfile` tRPC procedure, WITHOUT the `profile.travelPreferences` field(s) — internal-only data stripped from this surface; clients must never depend on them. Response shapes are intentionally not modeled in this spec; the native client types them by hand.
'400':
description: Request validation failed or the router rejected the input
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'401':
description: Missing or invalid bearer session token
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'426':
description: Reported X-GMH-App-Version is below the supported minimum — the app must update
content:
application/json:
schema:
$ref: '#/components/schemas/UpgradeRequiredError'
'500':
description: Unexpected server error (opaque; details stay in logs)
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
operationId: getV1AccountProfile
x-operation-id-source: derived
patch:
tags:
- Account
summary: Update the signed-in user's profile
description: 'Runs `user.updateProfile`. PARTIAL update: send only the fields being changed. An omitted field is left untouched — it is not cleared — and at least one field must be present or the call is a 400. There is no clear-a-field verb: no field accepts JSON `null` (that is a 400 too), so a value can only be replaced, never erased. `name` is the field this route exists for. It writes `user.name`, the name the Settings account row and the checkout guest form both render, and it is the only writer of that column outside admin tooling — Sign in with Apple hands back a name on the first consent only, so for most native accounts it starts empty and stays that way until this call runs. An all-whitespace name is ignored rather than written (and an empty string is a 400), so a stray save cannot wipe a name the customer already set. CHANGING `phone` DELIBERATELY RESETS that number''s verified state — `phoneVerifiedAt` goes back to null, so booking-confirmation SMS stops being delivered until the customer re-runs `POST /v1/phone/request-otp` then `POST /v1/phone/verify-otp`. Any screen with a phone field must say so and send them back through that flow; the reset is an audit fix, because without it a profile update could point a stay''s confirmation SMS at another number while inheriting the old verification. `dateOfBirth` is an ISO-8601 date string (`YYYY-MM-DD`), not a Unix timestamp. `nationality` and `country` are ISO 3166-1 alpha-3; `preferredCountry` is alpha-2, and the three preference fields are enum-validated against the supported currency/language/country lists, so an unsupported value is a 400 rather than a silently stored string. `avatarUrl` must be HTTPS (or an empty string). Returns `{ success: true }` only — it does not echo the saved row, so refetch `GET /v1/account/profile` when the screen needs to show what was stored.'
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
name:
type: string
minLength: 1
maxLength: 255
phone:
anyOf:
- type: string
maxLength: 80
- type: string
minLength: 0
maxLength: 0
dateOfBirth:
type: string
format: date
nationality:
type: string
minLength: 3
maxLength: 3
preferredCurrency:
type: string
enum:
- USD
- GBP
- EUR
- INR
preferredLanguage:
type: string
enum:
- en
- es
- fr
- de
- zh
- hi
- pt
- it
- ja
- te
- gu
- ko
- bn
- ru
preferredCountry:
type:
- string
- 'null'
enum:
- US
- CA
- DE
- FR
- IT
- ES
- NL
- BE
- AT
- IE
- PT
- FI
- GR
- LU
- SI
- SK
- EE
- LV
- LT
- MT
- CY
- HR
- SE
- DK
- PL
- CZ
- HU
- RO
- BG
- 'NO'
- IS
- LI
- CH
- GB
- GG
- JE
- IM
- IN
address:
type: string
maxLength: 500
city:
type: string
maxLength: 255
state:
type: string
maxLength: 255
country:
type:
- string
- 'null'
minLength: 3
maxLength: 3
postalCode:
type: string
maxLength: 20
avatarUrl:
anyOf:
- type: string
maxLength: 2048
format: uri
- type: string
enum:
- ''
description: Partial update. Every field is optional and an omitted field is left unchanged — this never clears anything. No field accepts null, so a stored value can be replaced but not erased. At least one field must be present.
minProperties: 1
responses:
'200':
description: Success
content:
application/json:
schema:
description: Verbatim JSON output of the `user.updateProfile` tRPC procedure. Response shapes are intentionally not modeled in this spec; the native client types them by hand.
'400':
description: Request validation failed or the router rejected the input
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'401':
description: Missing or invalid bearer session token
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'426':
description: Reported X-GMH-App-Version is below the supported minimum — the app must update
content:
application/json:
schema:
$ref: '#/components/schemas/UpgradeRequiredError'
'500':
description: Unexpected server error (opaque; details stay in logs)
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
operationId: patchV1AccountProfile
x-operation-id-source: derived
/v1/account/export:
post:
tags:
- Account
summary: Export everything we hold about the signed-in user
description: Runs `user.exportMyData`, the same GDPR/DSAR export the web profile downloads as `gmh-data-export-.json`. Returns one JSON document (profile, addresses, saved cards without provider tokens, bookings, reviews, chats, support tickets, notifications, consents and more); hand it to the share sheet as a file rather than rendering it. Each call is recorded as a data-access request. Takes no input, so this route accepts no request body.
security:
- bearerAuth: []
responses:
'200':
description: Success
content:
application/json:
schema:
description: Verbatim JSON output of the `user.exportMyData` tRPC procedure. Response shapes are intentionally not modeled in this spec; the native client types them by hand.
'400':
description: Request validation failed or the router rejected the input
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'401':
description: Missing or invalid bearer session token
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'426':
description: Reported X-GMH-App-Version is below the supported minimum — the app must update
content:
application/json:
schema:
$ref: '#/components/schemas/UpgradeRequiredError'
'500':
description: Unexpected server error (opaque; details stay in logs)
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
operationId: postV1AccountExport
x-operation-id-source: derived
/v1/account/memory:
get:
tags:
- Account
summary: Read what the assistant remembers about the user
description: 'Runs `user.getMemoryNote`. Returns `{ note }`: the free-form note the assistant reads on every chat turn, plus any preferences it learned on its own, as one editable string. An empty string means nothing is remembered.'
security:
- bearerAuth: []
responses:
'200':
description: Success
content:
application/json:
schema:
description: Verbatim JSON output of the `user.getMemoryNote` tRPC procedure. Response shapes are intentionally not modeled in this spec; the native client types them by hand.
'400':
description: Request validation failed or the router rejected the input
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'401':
description: Missing or invalid bearer session token
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'426':
description: Reported X-GMH-App-Version is below the supported minimum — the app must update
content:
application/json:
schema:
$ref: '#/components/schemas/UpgradeRequiredError'
'500':
description: Unexpected server error (opaque; details stay in logs)
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
operationId: getV1AccountMemory
x-operation-id-source: derived
put:
tags:
- Account
summary: Replace what the assistant remembers about the user
description: 'Runs `user.setMemoryNote`. Replaces the whole note (up to 4000 characters); learned preferences shown by `GET /v1/account/memory` are folded into it, so send back the edited text, not a delta. An empty or whitespace-only `note` clears the memory. Returns `{ success: true }`.'
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
note:
type: string
maxLength: 4000
required:
- note
responses:
'200':
description: Success
content:
application/json:
schema:
description: Verbatim JSON output of the `user.setMemoryNote` tRPC procedure. Response shapes are intentionally not modeled in this spec; the native client types them by hand.
'400':
description: Request validation failed or the router rejected the input
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'401':
description: Missing or invalid bearer session token
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
'426':
description: Reported X-GMH-App-Version is below the supported minimum — the app must update
content:
application/json:
schema:
$ref: '#/components/schemas/UpgradeRequiredError'
'500':
description: Unexpected server error (opaque; details stay in logs)
content:
application/json:
schema:
$ref: '#/components/schemas/ApiError'
operationId: putV1AccountMemory
x-operation-id-source: derived
components:
schemas:
UpgradeRequiredError:
type: object
properties:
error:
type: object
properties:
code:
type: string
enum:
- UPGRADE_REQUIRED
message:
type: string
minVersion:
type: string
example: 1.2.0
platform:
type:
- string
- 'null'
required:
- code
- message
- minVersion
- platform
required:
- error
ApiError:
type: object
properties:
error:
type: object
properties:
code:
type: string
example: NOT_FOUND
message:
type: string
example: Booking not found
domainCode:
type: string
example: NON_REFUNDABLE_CONSENT_REQUIRED
issues:
type: array
items:
type: object
properties:
path:
type: string
message:
type: string
required:
- path
- message
required:
- code
- message
required:
- error
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: 'Better Auth session token. Obtain it from the native /api/auth/* endpoints (Better Auth bearer plugin — out of scope for this spec, see #922).'
x-provenance:
method: harvested
publisher: GetMyHotels
source: https://api.getmyhotels.com/v1/openapi.json
note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
stamped by stamp-openapi-provenance.py (roadmap#793)