Every search-scoped id in the API (searchId, trip id, fare id, rate id) is opaque and expires. A 404 on one that worked before means it expired: create a new search and rethread. Retrying the same id never recovers. These ids are also context bound: a trip id only resolves with the searchId it came from.
Not every id expires. A hotelId is opaque too, but it names a stable entity rather than a snapshot inside one search, so it keeps working: a 404 from GET /v1/hotels/{hotelId} or its /reviews means the hotel is unknown, not that anything expired, and searching again will not help.
Links that do not expire
Two operations hand someone a link that outlives the search behind it: getFlightSearchLink (/v1/flights/search-link) and getHotelSearchLink (/v1/hotels/search-link). They take your own route, dates and occupancy rather than a searchId, so there is no snapshot to go stale, and they show live prices whenever the recipient opens them. From the CLI: wego flights share and wego hotels share.
Every link the API returns says which kind it is. A booking or checkout link carries "expires": true, a share link "expires": false, so a client never has to infer it from the endpoint it called.