Skip to navigation

Personas

Generate a per-member entertainment persona, and list the airline’s archetype gallery.

A persona is a per-member behavioral profile — genre affinities, retail interests, engagement and monetization signals — that shapes scored serves and suggestions. This page covers generating one for a member, and listing the airline’s selectable archetype gallery.

Generate a persona

POST /v1/personas/generate drafts a persona for one member from declared traveler attributes. It is session-scoped — requires the X-Session-Id header — and Deep-tier (it makes a model call). Body (max 16 KiB; each string attribute max 100 chars):

FieldRequiredRules
seatIdyesThe member’s seat.
ageBandyesDeclared band — a generation input only, never the authoritative age tier (that comes from session setup).
travelPurposenoThe purpose of the trip. Any text is accepted. Recommended values: business, leisure, visiting friends or family, adventure, first flight.
cabinClassnoThe traveler’s cabin. Any text is accepted. Recommended values: economy, premium economy, business, first.
groupTypenoThe traveler’s party. Any text is accepted. Recommended values: solo, couple, family, friends, group.
memberSlotnoWhich member on a shared seat. Omit for solo.
declaredGenrePreferencesnoObject of genre → strength (0–100), up to 40 entries.
retailInterestsnoArray of interest labels, up to 20.
language, contentStylenoOptional preferences.

Send travelPurpose, cabinClass and groupType when you have them; omit them, or send null, when you do not. A value that is sent must not be blank and is at most 100 characters. The recommended values are suggestions, not a closed list. A persona generated without one of these fields carries no declared value for it, and the response omits that property.

curl -X POST "https://api.staging.westiq.ai/v1/personas/generate" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "X-Session-Id: seat-12A-f3d9c1" \
-H "Content-Type: application/json" \
-d '{
"seatId": "12A",
"ageBand": "35-44",
"travelPurpose": "leisure",
"cabinClass": "economy",
"groupType": "family",
"declaredGenrePreferences": { "Drama": 80, "Comedy": 60 }
}'

The 200 response is a PersonaRecord:

{
"schemaVersion": "1",
"featureSchemaVersion": "1",
"airlineId": "demo_airline",
"sessionId": "seat-12A-f3d9c1",
"seatId": "12A",
"description": "A leisure traveler who leans into character-driven drama…",
"embedding": [0.012, -0.043, "…"],
"generatedAtMs": 1751558490000,
"genreAffinities": { "Drama": 82, "Comedy": 58, "Action": 0 },
"retailCategories": ["Noise-cancelling headphones", "Travel wallets"],
"engagementScore": 71,
"monetizationPropensity": 44
}
  • description is model-generated free text. genreAffinities, retailCategories, engagementScore, monetizationPropensity are the structured, code-normalized fields — present once the persona is generated (genreAffinities is filled to zero across the canonical genre vocabulary).
  • embedding is a similarity vector, useful for archetype/content matching.
  • Null-valued fields are omitted from the response, not sent as null — a solo traveler’s record simply has no memberSlot key, for instance.

Generation is idempotent per session + member. Calling generate again for a member who already has a persona returns the same record (200, no new model call, no second write) — the record is written once per session and never overwritten. To re-profile, use a new session. There is no rules fallback: if generation genuinely fails, it surfaces as a generic 500 internal.error — quote the correlationId.

Errors: 400 session.unresolved, 401 / 403, 422 request.validation (a required attribute missing/blank, an attribute over 100 chars, too many retailInterests/declaredGenrePreferences), 429 rate.limited over the per-client request-rate limit (honor the Retry-After header), 500.

List archetypes

GET /v1/personas returns your airline’s selectable persona archetype gallery — the pre-computed clusters a seatback UI can offer as a starting point. It is airline-scoped: no X-Session-Id, no parameters.

curl "https://api.staging.westiq.ai/v1/personas" \
-H "Authorization: Bearer $ACCESS_TOKEN"
{
"schemaVersion": "1",
"correlationId": "req_0197c0a1b2c3d4e5f60718293a4b5c6d",
"archetypes": [
{
"featureSchemaVersion": "1",
"airlineId": "demo_airline",
"archetypeId": "family-adventurers",
"label": "Family adventurers",
"clusterRank": 1,
"statisticalFingerprint": { "genre:Adventure": 0.71, "retail:Toys": 0.4 },
"refreshedAtMs": 1751558490000
}
]
}
  • archetypeId is stable within the airline — pass it as a member’s archetypeId in session setup to seed their persona.
  • clusterRank is 1-based (1 = largest/most significant cluster).
  • An airline with no seeded gallery gets an honest empty archetypes list — never another tenant’s archetypes.

Errors: 401 / 403, 500.