The current GraphQL schema does not expose a streamlined annual equivalent to the single-trip purchasePolicy mutation. Do not submit annual quote data to purchasePolicy.
Operation Summary
Step
Operation
Purpose
Value to retain
1
annualPlanQuote
Return eligible annual products and coverage choices
Securely capture card data, process payment, and automatically bind the staged annual policy
paymentSessionId; reconciled planNumber and policy result
Keep API credentials and payment verification on your backend. See Single Trip Quote & Purchase for the common authentication headers and payment identifier distinctions.
Flow
MERMAID
sequenceDiagram
autonumber
actor Traveler
participant App as Partner app
participant Backend as Partner backend
participant API as Travel Insured GraphQL API
participant Payment as Approved payment flow
Traveler->>App: Enter annual coverage and traveler details
App->>Backend: Request annual products
Backend->>API: annualPlanQuote
API-->>Backend: quoteNumber and annual products
Backend-->>App: Display products and prices
Traveler->>App: Select annual product
Backend->>API: stageAnnualPolicyPurchase
API-->>Backend: planGuid
Backend->>Payment: Create payment session for planGuid
Payment-->>Backend: paymentSessionId, embedToken, expiresAt
Backend-->>App: Short-lived widget configuration
App->>Payment: Submit card in hosted PCI form
Payment->>Payment: Process payment and bind policy
Payment-->>App: Payment or policy UX event
Backend->>Backend: Reconcile authoritative policy status
Backend-->>App: Return issued policy confirmation
Use this request when the customer is purchasing annual coverage without supplying a known trip. Do not use it when the quote included a trip segment that must be carried into staging.
effectiveDate is the requested start of annual coverage.
Supply exactly one traveler with primaryTraveler: true.
Assign a unique integer id to every traveler.
Keep each ID associated with the same person through quote and staging. These IDs also connect travelers to an optional trip segment.
Names and email are nullable in the quote schema, but collect enough identity context to prevent traveler mismatches before purchase.
Optional Trip Segment
Include tripSegment when the annual quote must also describe a known trip. It requires departure and return dates, at least one destination, and its traveler list.
The segment is optional when no trip is known. When present in the quote, carry it forward with the same traveler IDs and confirmed values. If dates, destinations, travelers, or costs change, request a fresh annualPlanQuote and stage from that new authoritative quote.
For no optional coverage, use "optionalCoverages": []. For a selected coverage, use the SDL-verified shape:
Multiple coverage entries are allowed. Each type code and limit ID must come from the selected annual quote product. Requote after the selection changes and use the refreshed authoritative amount for payment.
deliveryType is a required String in the published SDL, which does not define allowed values or casing. Email reflects the observed integration request shape but requires Travel Insured API Owner Confirmation as the canonical runtime value.
The stage response contains only planGuid. Keep the quote number, effective date, selected premium, travelers, and payment state in server-side checkout state.
Step 3: Complete Payment
From your backend, create an embedded payment session with the returned planGuid, current approved amount, billing contact, and billing address. Return only the short-lived session values required to mount the widget. Do not call processPayment; payment-session creation replaces that partner-orchestrated mutation.
The widget captures card data only in the Travel Insured-hosted PCI form. After successful capture, the embedded payment app processes payment and automatically binds the annual policy on the backend. Treat widget events as UX signals. Poll the session status from the partner backend and require both status and bindStatus to be Bound before confirming issuance.
Do not call processPayment or policyBindRequest; the embedded payment app handles that orchestration behind the scenes. Follow the Payment Integration Guide for the complete session and security contract.
Persist After Issuance
Store planNumber as the durable annual-policy identifier.
Retain paymentSessionId for authoritative server-side status polling and support correlation.
Protect policy documents and traveler data with server-side object-level authorization.
Use searchPlan with planNumber to retrieve the issued plan for later servicing.
Preserve traveler and segment identifiers returned by plan search before starting annual modification.
Failure and Retry Rules
Failure point
Recommended action
Annual quote fails
Correct inputs; do not substitute a single-trip quote
Annual inputs change
Request a fresh annual quote and replace the selection
Staging fails
Correct the request; do not begin payment without planGuid
Payment or binding is pending or unknown
Poll the payment-session status with bounded backoff; do not call payment or bind mutations
Final policy result is uncertain
Reconcile the existing session before retrying session creation
Do not log API credentials, payment data, or complete traveler records. Apply authorization before returning quote, payment, policy, or document data to a browser session.