Two independent workflows
Misfora is really two things running on the same data model: a document-processing pipeline and a reservation-sync pipeline. They meet at the guest record.
Guest document processing
Collecting and validating guest identity documents.
Instead of manually entering passport information at reception, guests receive a secure check-in link before arrival and upload a photo of their document with their own phone. Misfora automatically:
- detects the document in the photo
- extracts MRZ information
- recognizes identity fields
- validates document consistency against the reservation
- stores the original image securely, separately from the OCR result
- allows multiple recognition attempts if a scan is unclear
Each uploaded document becomes a structured digital identity, not just an image file.
No app to install
The guest side runs entirely in the browser — camera, upload, and confirmation all happen on a page opened from a link, nothing to install. For something a guest does once, for one stay, asking them to install an app just for that is real friction to overcome for very little payoff on their end.
Staff tools are web-based today for the same reason. A dedicated manager app isn't off the table for the future, but it solves a different problem — the web-first choice matters most on the guest side, where the alternative is a one-time app install nobody wants.
Not just any photo — live capture quality checks
A blurry or half-cropped photo is the single biggest cause of failed OCR, so Misfora doesn't let one through in the first place. Every frame from the guest's camera is scored in real time, continuously, before anything is ever uploaded:
- Sharpness — measured across multiple regions of the frame rather than one overall average, so a photo that's sharp in the middle but blurred at the corners still gets caught
- Brightness — rejects underexposed shots before they reach OCR instead of after
- Glare — catches reflections off a laminated card or a passport's bio page
- Document edges — a contrast threshold that adapts to the background (not one fixed number for every surface), checking that all four sides of the document are actually inside the frame and not cut off
On-screen guidance reacts immediately — too dark, move to a darker background, glare, tilt the document — instead of accepting whatever the guest happened to hold up. A frame only counts once it passes every check for a sustained run of ticks, not a single lucky moment, so brief flicker or a passing shadow doesn't falsely block or falsely pass a shot.
Once a good frame is found, capture happens automatically — the guest doesn't need to guess the right moment to tap a shutter button — and the file that actually reaches OCR is saved at near-lossless quality, not re-compressed on the way in.
Four ways to get a document scanned
The pre-arrival email is the default path, but it's not the only one — front-desk staff aren't stuck waiting on it:
Guest gets a secure link by email ahead of check-in and scans on their own phone, no staff involved.
One click opens the same camera flow directly on the staff member's own device — no link, no email, guest scans right there at the desk.
Staff can upload a photo of the guest's document on their behalf, straight from the guest table.
Generate a fresh, single-guest link per row — copied to clipboard or opened directly, independent of the automatic email.
All four feed the same pipeline below — the system doesn't need to know or care which path a given document came through.
Reaching a guest who hasn't responded
If a guest's link is still sitting unopened close to arrival, staff don't need a phone number lookup service to nudge them. Every guest row carries ready-made click-to-chat links for WhatsApp, Viber, and Zalo — official deep-link schemes (wa.me, viber://chat, zalo.me) that work for any registered number, plus a Telegram link that works only if the guest has phone-number visibility enabled in their own privacy settings (flagged in the UI, since it's not guaranteed the way the other three are).
One click opens a chat with the guest already addressed — no typing a number, no app switching to find the right contact. A dedicated pending guests view in the dashboard surfaces exactly who still needs a nudge (link opened but not finished, or expired without a response), with the same one-click links right there, so staff aren't scanning the whole guest table to find who to follow up with.
Nothing is sent automatically and no number is silently checked for a messaging account — none of WhatsApp, Viber, or Telegram expose a legitimate way to verify an arbitrary number without contacting it, so Misfora doesn't try. Every link is just a ready door into a chat that a staff member opens themselves, if and when they decide to.
Supported documents
Misfora is built around ICAO-compliant travel documents.
TD3 MRZ (two 44-character lines), the standard ICAO passport format.
TD1 MRZ (three 30-character lines). A dedicated OCR path handles the ID-1 card format.
The OCR layer is document-type aware by design — adding a new document type means adding a new adapter, not touching the rest of the platform. Candidates for future support: national ID cards, residence permits, driving licenses, and other country-specific travel documents.
Extracted information
What Misfora reads off a scanned document.
The original image is preserved separately from the OCR result, so a document can be re-processed later with an improved recognition engine without asking the guest to upload it again.
Confidence & validation
Recognition isn't a single pass/fail — it's field-level, and it remembers what's already confirmed.
This starts from a good input: the live capture quality checks above mean OCR is running on a sharp, well-lit, properly framed photo far more often than not — reliability starts before the image ever reaches the recognition engine.
Instead of treating a document as "recognized" or "not recognized" as a whole, Misfora scores three independent blocks separately: surname, given name, and everything else — the second group has MRZ checksums behind it, so it's inherently more reliable than name spelling.
Once a block is recognized with high confidence, it's locked. A later re-scan can fill in whatever is still missing or unconfirmed, but it can no longer overwrite a block that already passed — a guest can't accidentally (or otherwise) replace data that's already been confirmed by re-uploading a different photo.
Mismatch detection
Every recognized document is compared against the reservation it belongs to. A small spelling difference is treated as a routine OCR correction; a large discrepancy is flagged for manual review instead of silently overwriting the booking, and the system distinguishes two cases: the guest appears to have uploaded the wrong document, or the document belongs to a different guest than the one it was assigned to on the reservation. Both route to the manager queue rather than getting auto-accepted.
Reservation & PMS synchronization
Connecting guest documents with hotel reservations.
Misfora synchronizes reservation data from supported PMS platforms and converts every reservation into a universal internal model. Instead of writing custom logic for every PMS throughout the app, Misfora normalizes reservation data into one structure that stays identical regardless of the source system — OCR, PMS sync, and government reporting all operate on that same structure.
OAuth client, webhook ingestion, and automatic backfill. In production use.
For properties without a connected PMS — reservations are entered directly.
The adapter pattern below is what makes adding another PMS a contained piece of work rather than a rewrite — nothing to announce yet.
New PMS systems are added through adapter modules without modifying the core platform — see Modular adapter architecture below.
Check-in, without opening the PMS
Once a guest's documents are confirmed and the stay is paid, a Check in button in the same guest table row writes the actual check-in time straight to the PMS — staff never have to switch over to Exely to do it manually. The button only becomes active once the backend independently confirms both conditions (document confirmed, nothing outstanding), not just the front-end state, and the click is idempotent: checking in an already-checked-in stay twice doesn't fire a second write. If the PMS is unreachable or rejects the request, nothing changes on either side and the action can simply be retried.
Room-mix reservations (several rooms under one booking) are handled the same way, with no extra logic — the same one-stay-at-a-time model already used everywhere else in the platform.
Unified guest model
Every reservation, regardless of PMS, follows the same lifecycle.
This universal chain is what separates business logic from PMS-specific implementations — the rest of the platform (OCR, dashboards, government reporting) never needs to know which PMS a given property runs on.
Government registration
Once guest information is collected, Misfora prepares it for government reporting.
Instead of scattering country-specific logic through the application, each destination country is connected through its own adapter that maps a stay + guest + document to that country's required payload.
Full SOAP integration, built against Turkey's mandatory guest-registration system.
Mapper structure exists; the exact Hospedajes/SES payload format is still to be confirmed against official documentation.
Managers can preview the exact payload that would be submitted for a guest before it's sent, from the admin dashboard. This adapter pattern is what lets a new country be added without changing the core check-in workflow.
Smart processing pipeline
The complete guest journey, from booking to compliance.
Reservation and PMS-sync events are processed in the background rather than on the request path — a webhook from the PMS is acknowledged immediately, and the actual sync work happens asynchronously, so it never blocks or delays guest check-in.
Each stay's progress (pending / partially completed / completed) is visible to hotel staff in the admin dashboard as guests complete their part.
Modular adapter architecture
Misfora was designed as an integration platform, not a single-purpose OCR tool.
Three parts of the system are isolated behind a shared adapter pattern — each has a base interface and a registry, so adding a new one doesn't require touching routes, models, or the database layer:
Map a raw PMS webhook payload into one universal reservation format. Exely today, with the structure built for more.
Map a document photo into recognized fields. One adapter per document type (passport, Kimlik), engine-agnostic.
Map a stay + guest + document into a specific country's reporting payload. Turkey KBS, Spain.
Guest notification is intentionally not built as a multi-provider adapter system: it's a single email channel (Resend, with SMTP as a fallback). SMS/WhatsApp/etc. aren't used to send anything automatically — see reaching a guest who hasn't responded above for what phone numbers are actually used for.
Secure by design
Guest privacy is built into the structure, not bolted on.
Misfora keeps three things as separate entities rather than one blob: the original document image, the raw OCR result, and the structured guest data derived from it. That separation is what enables secure storage, controlled access, and future re-processing with a better recognition engine — without ever asking a guest to upload their document a second time.
Why this architecture
Traditional hotel workflows re-enter the same guest information into multiple systems by hand. Misfora turns that into one automated process.
One document. One workflow. Multiple connected systems.
See how the Exely PMS integration works step by step, including the webhook and API-key setup.