SkyCop Business · PRD v1.3 review

Travel Agency Lead Channel — Logic, Journeys & CTO Assessment

Agencies feed PII-free sold-flight data; SkyCop detects disrupted, claimable flights; a human agent converts the passenger into a signed claim. This is the working model, the customer journeys, how each role operates, and where the real risk sits.

Source: SkyCop_Business_PRD_v1.3.md (Peter) Pilot agency: BPC Travel Reward unit: per passenger (~1.6×/claim) Drafted 2026-06-08 · CTO office

1The model in one paragraph

Travel agencies send SkyCop a daily, PII-free feed of flights they sold (flight number, carrier, times, origin/destination — no names, no PNR). SkyCop watches those flights via OAG; when one is cancelled or delayed 3h+ and the scoring model says it's worth pursuing, it becomes a Flight lead in a new CRM, "SkyCop Business". A human agent opens the lead, reverse-looks-up which of their own customers were on that flight (inside the agency's own system — SkyCop never sees it), phones/WhatsApps them to sell the idea, then emails a pre-filled skycop.com claim form. The passenger edits, uploads docs, signs & submits. SkyCop pays the agency a fixed reward per submitted passenger — not per claim, not per legal win.

2System logic — end-to-end pipeline

The pipeline is fully automated up to the Flight lead. From there, everything depends on a human agent.

flowchart TD
    A["Agency exports sold flights
Amadeus Agency Insight → XLSX"] -->|"daily automated email"| B["SB1 · Flight-feed ingestion"] B --> C{"Validate · normalize
dedup · idempotent"} C -->|"errors"| C1["Import error log
NO PII"] C -->|"ok"| D["Sold flight records
flight data only"] D --> E["SB3 · Disruption detection
at / after scheduled departure"] E --> F{"OAG: cancelled
or delayed 3h+?"} F -->|"no"| Z["No side effects
no lead · no email · no report"] F -->|"yes"| G["SB2 · Scoring API wrapper
wraps existing model R1"] G --> H{"Score ≥ claimable threshold?"} H -->|"no"| Z H -->|"yes"| I["FLIGHT LEAD created · SB4"] I --> J{"Agent id present
in feed?"} J -->|"yes"| K["Assigned → Incoming
agent emailed"] J -->|"no"| L["Unassigned
Owner / Admin emailed"] L -->|"Owner/Admin assigns"| K K --> M["Agent works the lead →"] style I fill:#2ee6b6,stroke:#1aa,color:#06231c style Z fill:#e9edf5,stroke:#bbb,color:#555 style L fill:#ffe1b0,stroke:#e0a050,color:#5a3b00

Claimable statuses: 01_green, 02_yellow, 03_obscure, 04_orange_light always; 04_orange only in good jurisdictions (UK, AT, FR, ES, RO, SE).

Claim sub-flow — what the agent actually does

flowchart TD
    M["Agent opens Flight lead"] --> N["Reverse-lookup passengers
in AGENCY system — manual, off-platform"] N --> O{"Matching
passengers?"} O -->|"no"| P["Mark 'No matching passengers'
+ reason + note"] O -->|"yes"| Q["Create one or more Claims
enter passenger PII"] Q --> R["Close Flight lead
→ work moves to Claims"] R --> S["Contact passenger by phone / WhatsApp
the live SALES step"] S --> T["Generate secure form link
+ Send templated email"] T --> U["Passenger: edit · upload docs · sign · submit"] U -->|"submitted"| V["Claim → Passenger submitted
Reward accrual PER passenger"] U -->|"refuses / already claimed"| W["Mark 'Passenger declined'
+ reason"] V --> X["Monthly payout batch
→ manual pay → Reward paid"] style S fill:#3da9fc,stroke:#1577c4,color:#021426 style V fill:#2ee6b6,stroke:#1aa,color:#06231c style N fill:#ffe1b0,stroke:#e0a050,color:#5a3b00

The two amber boxes are the bottlenecks: the off-platform reverse-lookup (R1) and the live sales call (the actual conversion engine).

3State machines

A Flight lead exists only before claim work; the moment claims are created, it closes and all work moves to Claims — avoiding a dual source of truth.

Flight lead lifecycle

stateDiagram-v2
    [*] --> Unassigned: created · agent unknown
    [*] --> Incoming: created · agent known
    Unassigned --> Incoming: Owner/Admin assigns
    Incoming --> Incoming: reassigned
    Incoming --> Closed_claims_created: add claim(s) + close
    Incoming --> No_matching_passengers: no match + reason
    No_matching_passengers --> Closed_claims_created: add claim (recovery)
    No_matching_passengers --> Incoming: Return to active
    Closed_claims_created --> [*]
  

Claim lifecycle

stateDiagram-v2
    [*] --> Filling_started: agent starts claim
    Filling_started --> Claim_form_ready: enough data · form sent
    Claim_form_ready --> Passenger_submitted: passenger signs + submits
    Filling_started --> Passenger_declined: refused / already claimed
    Claim_form_ready --> Passenger_declined: refused / already claimed
    Passenger_declined --> Filling_started: Return to active
    Passenger_submitted --> Reward_paid: in a paid payout batch
    Reward_paid --> [*]
  

Payout batch lifecycle (monthly · manual money movement)

stateDiagram-v2
    [*] --> Draft: system generates from accruals
    Draft --> Reviewed: Account Manager checks
    Reviewed --> Exported: payout file exported
    Exported --> Paid: accounting pays + Mark as paid
    Paid --> [*]: accruals & Claims locked
  

4Customer journeys

Happy path — flight sold → reward paid

sequenceDiagram
    autonumber
    participant AG as Agency feed
    participant SB as SkyCop Business
    participant OAG as OAG + Scoring
    participant AGT as Agent
    participant PAX as Passenger
    participant SC as skycop.com form
    participant ACC as Accounting
    AG->>SB: daily XLSX (flight data, no PII)
    SB->>OAG: monitor each flight at/after departure
    OAG-->>SB: disrupted + claimable
    SB->>AGT: Flight lead (email + Kanban card)
    Note over AGT: searches AGENCY system
for passengers on this flight AGT->>SB: create Claim(s), enter passenger PII AGT->>PAX: phone / WhatsApp — SELL the idea AGT->>SB: generate link + Send email SB->>PAX: templated email + secure form link PAX->>SC: edit prefilled fields, upload docs, sign, submit SC-->>SB: submission event SB->>SB: Claim → Passenger submitted; accrual per passenger Note over SB: existing SkyCop claim lifecycle (R2) takes over SB->>ACC: monthly payout export ACC-->>SB: Mark as paid → Claims → Reward paid

Variant paths

VariantWhere it forksOutcome
Unassignedfeed has no agent idOwner/Admin must manually assign before any work starts
No matching passengersagent can't find anyone on the flight in agency systemlead closed unworked (reason: not found / pax not on flight / other)
Passenger declinedpassenger refuses or already claimed elsewhereclaim closed, no reward (+ reason + note)
Mis-click recoveryagent wrongly set decline / no-match"Return to active" or add-claim auto-reopens
ReassignmentOwner/Admin moves lead to another agentnew owner gets access + email; old owner keeps only a saved deep link; others blocked (non-enumerable IDs)

5Role playbooks — how everybody works on the platform

SkyCop Business CRM

Agent — the engine

  • Sees only own leads, own claims, own reward
  • Kanban, no drag-and-drop; stages move on events
  • Loop: open lead → find passengers in agency system → create claim + PII → close lead → call/WhatsApp & sell → send form → chase
  • Paid per passenger, only on submission
SkyCop Business CRM

Agency Owner / Admin

  • Owner = root, always Admin, can't be demoted
  • Assigns / reassigns the Unassigned pile
  • Monitors discipline: age-in-stage, conversion, no-match & decline rates, last activity
  • Invite / promote / suspend agents (blocked while live claims exist)
Admin app

Account Manager

  • Creates agency, sets reward config + bank details
  • Tracks lifecycle (Trust → Signing → Implementation → Active → Ended)
  • Reviews & exports monthly payout file
  • Clicks Mark as paid after accounting pays
Admin app

Admin

  • Everything Account Manager can do
  • Default view: all agencies
  • Can change an agency's main owner
skycop.com

Passenger

  • Gets the agent's call, then the email
  • Opens pre-filled single-page form via secure link
  • Edits, uploads docs, signs (= consent + exclusive rights assignment), submits
  • Then the existing SkyCop claim lifecycle handles it
Automated

SkyCop system

  • Ingest feed → detect disruption (OAG)
  • Score → create Flight lead
  • Notify agent or Owner/Admin
  • Accrue rewards, generate payout batches

6CTO assessment

Each point restates what the PRD says (context), then my take and a recommendation — so you don't have to re-read the doc to follow it.

strength highest risk high medium

What's genuinely good

PII-free feed — the smartest decision in the docstrength
Context§3 + §11.2 + §20 — the agency sends only flight data; passenger PII enters only when the agent manually creates a claim draft.
It collapses the legal surface from "mass-PII controller holding every agency's customer list" to "per-claim processor under a DPA." Everything legal downstream rests on this invariant — keep it sacred.
Per-passenger reward aligns with SkyCop's own revenue logicstrength
Context§3 + §17.2 — reward unit is passenger (~1.6 pax/claim, ~1.6× per-claim cost), chosen deliberately.
SkyCop earns per passenger; paying per passenger keeps the incentive math honest for agency and agent. No notes.
Human-in-the-loop sales step is honest about realitystrength
Context§3 — the agent must phone/WhatsApp the passenger before the email because "email-only conversion is expected to be very low."
The product is built around the agent's warm relationship, not a cold email. That's the real conversion engine and the doc names it.

Risks, ranked by how much they can hurt v1

R1The flight → passenger reverse-lookup is the load-bearing step — and it's hand-wavedhighest
Context§3 + §9.2 — the feed has no PII and no PNR, so the agent must go into the agency's own system and figure out which customers were on flight SK1234 on a given date. The PRD models the outcome ("No matching passengers") but never the how.
The entire funnel's throughput is this manual lookup. If it's slow or unreliable in Amadeus/the back-office, agents quietly stop working leads and the channel dies — regardless of how good our pipeline is. It's an agency-side workflow we can't see or control, and it's invisible in the spec.
Recommendation: make "minutes-to-match" and "% leads matched" the #1 success metric of the BPC pilot, above conversion. If matching is painful, the model needs rethinking before agency #2.
R2Attribution gap → "Unassigned" becomes a floodhigh
Context§3, §10.3, §12.7 — agent id in the feed is optional; without it every lead lands in Unassigned and the Owner/Admin is emailed to assign it manually.
Amadeus Agency Insight exports may not cleanly carry "which agent sold this ticket." If they don't, every lead is a manual assignment + an email — at volume the Owner drowns and the SLA collapses before an agent ever touches a lead.
Recommendation: confirm during the BPC data exchange (Open Q #2/#3) whether agent id is reliably present. If not, plan an assignment helper (bulk / round-robin / office-level) and digest the Unassigned emails, not one-per-lead.
R3Reward-on-submission vs legal-success = direct financial exposure, gated by one modelhigh
Context§3 + §17.1 — reward triggers on passenger submission, "no dependency on legal success." Claimability is decided solely by the scoring model (§10.2), reused unchanged behind an API wrapper.
SkyCop pays for every submission but only earns when the claim legally wins and the airline pays. The spread between submission rate and success rate is SkyCop's loss exposure. If the model is loose (high false-positive), this channel can be loss-making per lead — and there's no feedback loop in the spec from real outcomes back to threshold tuning or a per-agency kill-switch.
Recommendation: monitor submitted → legally-successful per agency and give Admin a pause / raise-threshold lever. "Who eats a wrongly-scored reward" is a founders' commercial-policy call, not just engineering.
R4SB11 reworks the live production claim form + needs a legacy integrationhigh
Context§15 — the existing skycop.com form (converting paid traffic at ~€25/claim today) must support pre-filled drafts, go single-page, accept a secure link, and fire a submission event back into SkyCop Business (Open Q #5), built into the legacy Symfony 3.4 monolith.
The riskiest engineering item: we touch the production funnel and build a new event contract into the legacy stack. R2 ("claim lifecycle after submission") is marked unchanged, but the hand-off seam is exactly where legacy pain lives.
Recommendation: build the pre-filled flow as a separate entry variant, never a rewrite of the existing form, so the paid funnel is never at risk. Nail the submission-event contract early — it blocks reward accrual, stage transitions, and payout reconciliation at once.
R5Connecting-flight compensation can be wrongmedium
Context§11.3 + §11.4 — EC261 amount depends on final destination, but PNR is excluded, so grouping relies on optional non-PII connection ids Amadeus may not provide (Open Q #3). Without grouping, the tier is a segment-based estimate.
Wrong tier → wrong "potential reward" shown to the agent and wrong expectation set with the passenger on the call. Erodes trust fast.
Recommendation: for the pilot, show compensation tier as an estimate with a confidence flag when grouping is incomplete. Don't let the agent quote a figure the claim can't deliver.
R6"Unsigned PII auto-deleted, non-recoverable" is easy to under-buildmedium
Context§20 + §21 — unsigned claim drafts containing PII must auto-delete after the retention window and not be recoverable through normal tooling.
"Non-recoverable" means no soft-delete, no lingering copies in backups/logs/the prefilled-form-link target. A real engineering constraint QA-by-screenshot won't catch — and a GDPR commitment we'd have to honour under audit.
Recommendation: design retention/delete as a first-class feature with a test proving the data is gone (incl. the form-link target). The window itself is blocked on legal (Open Q #1).
R7Dedup brittleness + cross-channel duplicate passengersmedium
Context§11.6 — dedup key is agency + carrier + flight no + departure datetime + origin + destination; multiple agent attributions on one flight are preserved.
(a) Exact-datetime keys are fragile — a re-sent file with a reformatted timestamp can slip past dedup and double the leads. (b) Nothing checks whether the passenger is already in SkyCop's funnel (paid search, direct, or another agency). The exclusivity clause covers the legal double-claim, not the operational waste.
Recommendation: normalize timestamps to UTC before keying (make it explicit). Park cross-channel passenger dedup as a known v1 gap; watch "Already claimed" decline rates in the pilot.
R8Agent unit economics are unstated (commercial, not technical)medium
Context§13.1 + §17.3 — agency sets total reward/pax and agent reward/pax; agent sees only their own.
Each lead costs the agent real time (lookup + call + entry + chase) and many decline. If agent reward/pax doesn't beat their normal commission work on an effective-hourly basis, they won't work leads — and R1's friction makes it worse. Not our model to set, but the product's success depends on it.
Recommendation: surface "potential reward" on the card (the PRD does — good) and feed real per-agent earned-vs-effort data to the agency early so they can tune the split.

Smaller flags — park, don't block

7Open questions still unanswered

  1. Unsigned-PII retention window — legal.
  2. Exact BPC/Amadeus XLSX format — columns, date formats, time zones.
  3. Can Amadeus provide a non-PII connection-group id for connecting flights?
  4. Claim-form passenger fields + document set — deferred to v1.3 after ops input.
  5. Claim-form API/event contract between SkyCop Business and skycop.com — blocks R4.
  6. Do agents need a table view in addition to Kanban?
  7. Per-agency connectors beyond BPC — separate projects, reusable framework desired.

8Bottom line

The architecture is sound and the GDPR instinct is excellent — the PII-free feed is the kind of decision that prevents a year of pain. The two things that decide whether this works are not in the software: (1) can agents actually reverse-match flights to passengers fast enough to bother (R1), and (2) is the scoring model tight enough that reward-on-submission doesn't bleed money (R3).

I'd run the BPC pilot instrumented to answer exactly those two questions before committing to the multi-agency connector framework. The biggest engineering risk is R4 — touching the live form plus the legacy submission event — so keep the pre-filled flow isolated from the paid-search funnel.