Concepts
Facts, producers and consumers, manifests, authority, the five dispositions and the other ideas the tools rely on, in plain language.
On this page
In short
HOS is a shared way for hotel systems to say what happened: each system publishes facts, declares what it publishes and which values it is the authority for, and every system that receives the facts applies the same rules. Ten ideas are enough to read everything the tools print.
The examples come from the Quickstart's morning: guest stay_1042 arrives early, and unit unit_204 is not ready.
A fact
A factFact (event)One thing that happened in a hotel system, such as a unit becoming clean, sent as a CloudEvent in the HOS format. It states what the source knows; it does not ask anyone to do anything., or event, is one thing that happened in a hotel system: a reservation was made, a room became dirty, a guest checked in. It says what the system knows, when and about what. It does not ask anyone to do anything.
In a hotel: a line in the front office log book. "06:40, housekeeping: room 204 dirty, the guest left."
Why it matters: when every system writes the same kind of line, any other system can read it, without a custom integration for each pair of systems.
Here is the fact of that line, as the housekeeping system publishes it:
{
"specversion": "1.0",
"id": "hk-002231",
"source": "urn:hos:housekeeping:demo",
"type": "unit.status_changed",
"time": "2026-07-30T06:40:00Z",
"datacontenttype": "application/json",
"hosschemaversion": "0.1",
"hosrecordedat": "2026-07-30T06:40:02Z",
"hostenant": "tenant_demo",
"hosproperty": "prop_demo",
"hospropertytimezone": "Europe/Paris",
"hosbusinessdate": "2026-07-30",
"hossubjects": "unit:unit_204",
"data": {
"unit_id": "unit_204",
"dimension": "housekeeping",
"previous": "inspected",
"current": "dirty",
"authority_source": "urn:hos:housekeeping:demo",
"reason": "departure"
}
}sourceis the system that published it, andidits number in that system: together, they identify the fact.typesays what happened: a unit's status changed.timeis when it happened, in UTC (theZ);hosrecordedat, when the system recorded it.hospropertyis the hotel, andhostenantthe organisation its data belongs to, such as a hotel group.hospropertytimezoneis the hotel's time zone, andhosbusinessdateits operating day.hossubjectsnames what the fact is about: unit 204.dataholds the detail: the housekeeping status of unit 204 went frominspectedtodirtywhen the guest left.
Technical detail
HOS events follow the CloudEvents format, with HOS attributes that start with hos. data is closed: only the fields its type defines are allowed, and vendor detail goes in data.extensions, under a namespace such as com.example. HOS Events 0.1 defines the fifteen types and every attribute.
Producers and consumers
A producerProducerA system that publishes HOS facts, such as a property management system (PMS) or a housekeeping app. Its manifest says what it publishes. publishes facts: a property management system (PMSPMSProperty management system: the hotel's main software for reservations, stays, rooms and billing, such as Mews, Apaleo or Cloudbeds.), a housekeeping app, a guest messaging platform. A consumerConsumerA system that receives HOS facts and decides what to do with each one. receives them and decides what to do with each one: a dashboard, an operations app, an AI assistant. One system can be both.
In a hotel: the housekeeper who reports a room's state, and the front desk that reads it before handing over a key.
Why it matters: the tools check each side differently. A consumer is tested with made-up scenarios; a producer is checked on what it actually publishes.
The manifest
A producer's manifestManifestA producer's declaration: the facts it publishes and for which properties, the values it is the authority for, how it delivers, replays and keeps them, and its known limitations. The producer signs it. is its declaration: the facts it publishes, for which hotels, the values it is the authority for, how it delivers them, how long it keeps them, and its known limitations.
In a hotel: a job description. "I report the cleaning status of rooms, and I have the last word on it. I also report whether a room is occupied, but the PMS has the last word on that."
Why it matters: a consumer processes only what a manifest declares. The manifest is how it knows whom to trust for what.
Part of the housekeeping system's manifest:
{
"hosmanifestversion": "0.1",
"producer": "urn:hos:housekeeping:demo",
"property_ids": ["prop_demo"],
"events": [
{ "type": "unit.status_changed", "dimensions": ["housekeeping"], "authoritative": true, "snapshot": true },
{ "type": "unit.status_changed", "dimensions": ["occupancy"], "authoritative": false, "snapshot": true },
{ "type": "housekeeping.task.created", "authoritative": true },
{ "type": "housekeeping.task.completed", "authoritative": true }
],
"limitations": ["The property releases units on inspection only, so the housekeeping status goes from dirty to inspected without a clean step."]
}Authority
The authorityAuthorityThe system of record for a value, such as the housekeeping app for a unit's cleaning status. Only the authority changes that value; facts from other systems are recorded and shown as conflicts, never merged into it. on a value is the system of record for it: the housekeeping system for cleaning, the PMS for occupancy. Only the authority changes the value. When another system disagrees, its fact is kept and shown as a disagreement, never merged into the value.
In a hotel: who has the last word on a room. The PMS may believe room 204 is clean because a task was closed; the supervisor who inspects rooms decides.
Why it matters: without it, the last system to speak wins, and a front desk may hand over a room nobody released. That is delivery 9 of the Quickstart.
The five dispositions
For each fact it receives, a consumer reaches one dispositionDispositionWhat a consumer does with a fact it receives: applied, or set aside as a duplicate, superseded by a later fact, non_authoritative when its producer is not the authority, or undeclared_capability when its producer did not declare it.. HOS Events 0.1 decides which, in this order:
1. Same source and id as a fact already received?
duplicate2. Declared by its producer's manifest, for this hotel?
undeclared_capability3. Is its producer the authority on it?
non_authoritative4. Is a later fact about the same thing already known?
supersededNone of the above
applied
| Disposition | When | In the Quickstart |
|---|---|---|
duplicate | the consumer has already received a fact with the same source and id | delivery 5 |
undeclared_capability | the producer's manifest does not declare this fact for this hotel | delivery 7 |
non_authoritative | the manifest declares it, but the producer is not the authority: it is only recorded | delivery 9 |
superseded | a fact about the same thing that happened later is already known | delivery 11 |
applied | none of the above: the fact changes what the consumer knows | the others |
Why it matters: facts can arrive twice, late or out of order, and from systems that are not the authority. With these rules, every consumer that receives the same facts reaches the same result.
Technical detail
"Later" compares the time of the two facts, then their source, then their id, so that every implementation breaks ties the same way. Unless the producer declares an ordering, delivery order never decides. The SDK exports these rules: factKey, isLater, findDeclaration and authority.
Streams
A streamStream (JSON Lines)A file of facts, one JSON object per line, usually named .jsonl, in the order they were delivered. is a file of facts in JSON Lines: one fact per line, in the order they were delivered, usually named .jsonl. A .json file holds one document; a .jsonl file holds many, one per line.
stay.expected.json
{
"specversion": "1.0",
"id": "pms-000421",
"type": "stay.expected",
...
}events.jsonl
1 {"id":"pms-000312", ...}
2 {"id":"pms-000421", ...}
3 {"id":"pms-000422", ...}
4 {"id":"hk-002231", ...}
Why it matters: some problems only show across facts: the same fact sent twice, two facts with the same id but different content, a fact that no manifest declares. hos validate checks a stream as a whole, and hos replay plays it back.
Conformance scenarios
A conformance scenarioConformance scenarioA made-up sequence of deliveries, with the manifests of its producers and the expected outcome. A system replays it and compares its results with the expected ones. is a made-up day in a hotel: the facts of several systems, in delivery order, the manifests of those systems, and the outcome HOS expects. HOS publishes three: an early arrival to a room not ready, a room out of order, and a late check-out.
Why it matters: a system that receives HOS facts can replay them and compare its answers with the expected ones, whatever its language. hos conformance run does it for you. All the data is made up: no guest or hotel data is involved.
Normative and reference
A scenario checks two things of different standing, which reports show apart:
- Normative: the dispositions. They follow the rules of HOS Events 0.1, and every conformant consumer must reach them.
- Reference: whether each arrival's room is ready, and the situations raised, such as "arrival at risk". They come from the reference projectionReference projectionThe way the SDK reads arrival readiness from the facts, to show what HOS makes possible. It is not normative: a consumer can assess arrivals differently and still follow HOS Events 0.1., one way to read arrivals that HOS gives as an example. It is not normative: a system may assess arrivals differently and still follow HOS.
Why it matters: a report of normative 13/13 says the system follows the rules. A difference at the reference level may only mean the system reads arrivals its own way. See Read a HOS report.
Signatures and key sets
A producer signsSignaturemanifest.jws, made with the producer's private key. It proves who declared the manifest and that nobody changed it since. It expires, 90 days after signing by default with hos, so the producer signs again before then. its manifest, so that a consumer can check who declared it and that nobody changed it since. It publishes three files on its website, under /.well-known/hos/: the manifest, its signature, and its public keys in a JWKSJWKSJSON Web Key Set: the public keys of a producer, published next to its manifest. Consumers use them to check the manifest's signature. The private key that signs stays with the producer., a JSON Web Key Set.
In a hotel: a wax seal on a letter, and the public register of seals that anyone can check it against. The seal itself, the private key, never leaves the producer.
Why it matters: a manifest decides what a consumer trusts. A manifest that fails verification counts as no manifest: nothing it declares is processed. A signature expires, 90 days after signing by default with hos, so the producer signs again in time.
Exit codes
Every hos command ends with an exit codeExit codeThe number a command returns when it ends, which scripts and CI read. hos returns 0 when everything is valid or passed, 1 when a file is invalid or a check failed, and 2 when the command is wrong or a file could not be read., a number that scripts and CI read without reading the text:
| Code | Meaning |
|---|---|
| 0 | everything is valid, or every check passed |
| 1 | a file is invalid, a check failed, or a signature does not verify |
| 2 | the command is wrong, or a file or URL could not be read |
Why it matters: a CI pipeline stops on any code other than 0, so a broken file or a failed scenario blocks a release before it reaches a hotel.
Next steps
- Quickstart: see these ideas at work in ten minutes.
- Glossary: every term in a few lines.
- HOS Events 0.1: the rules themselves.