PMS v1 facade

Migration without a rewrite. Every legacy apc-integrator.php method has a byte-parity faΓ§ade at /v1/qc/pms-v1/*. Responses match the old endpoint under a locked test corpus, so you upgrade one method at a time and rollback is literally changing one URL back. This is the anti-thesis of "we're deprecating v1, migrate by Q4" β€” see Why Quendoo Connect for the full case, and the migration guide for the map of every legacy method to its modern QC endpoint.

Legacy integrators know Quendoo through the apc-integrator.php API β€” what the platform has always exposed as PMS v1. QC's job is to replace that surface without breaking the callers still on it.

You do not have to do anything to keep working. The facade owns the byte-parity guarantee β€” every response your PMS reads today keeps the same shape, the same field names, the same header set, and the same error strings. If we can't match a byte, we don't answer.

Ready to move? The migration guide maps every PMS v1 method to its modern QC endpoint.

The cutover lifecycle

Every PMS v1 method walks a three-state path. Which state a given api_user is in for a given method is decided by our operations team from a single table (qc_v1_cutover) β€” never by which URL you call.

State What runs What you see
Unknown Legacy answers directly. The QC facade is not in the loop. Same bytes as always.
Shadow The QC facade computes an answer locally with no side effects, calls legacy in parallel, records the byte-diff in qc_v1_shadow_diffs, and returns legacy's bytes. Same bytes as always.
Live The QC facade answers on its own. Legacy is not consulted. Same bytes β€” because shadow proved it.

The state is per api_user, not per property. That lets us shadow a single friendly integrator, watch the diff score, tighten the last gaps, then flip only that integrator to live. Every other caller stays on legacy until we flip them too.

You will never be flipped to live for a method whose shadow score isn't already zero.

Method catalogue

Locally implemented β€” every method below runs through the QC facade today. Which state your api_user is in for it decides whether the local answer is only recorded (shadow) or returned (live).

Proxied to legacy β€” anything not in the list above still routes through the same door, but the facade forwards the raw request to legacy without touching it. As we port more methods this list shrinks and the catalogue above grows.

What "byte-parity" means in practice

The shadow harness compares the response body the facade would have returned against the body legacy did return. A diff means:

All four count as regressions. Ordering-only diffs on set-typed lists (like guests[]) are the one exception the harness whitelists β€” every other diff must resolve to zero before a method flips to live for anyone.

What changes for you

Nothing. The URL, the query params, the response envelope, the api_key, the error strings β€” every one of those stays. Your integration is compatible with v1 the whole time. When a method of yours is running on QC (live), the only difference is that our answer no longer depends on the legacy database being reachable.

For work you're starting today or building a new integration: prefer the modern /v1/qc/* surface (see integration guide). It is the same platform underneath, without the byte-parity constraints v1 carries.

What we watch

Neither of these is a signal you can see. Ask us for the score on any method that matters to you.