{"openapi":"3.1.0","info":{"title":"Easia Hub API","version":"0.1.0","description":"API contract and integration documentation for Easia Hub.\n\n## What is documented here\n\n- The first-party Easia Hub APIs under `/api/v1`.\n- The implemented HubSpot partner-directory and behavioral-event bridge.\n- The implemented KOOB product-mapping and signed launch handoff.\n\n## Documentation model\n\nThis portal uses an OpenAPI 3.1 document rendered through Swagger UI. The contract is the source of truth for:\n\n- request and response shapes,\n- integration mode signaling (`fixture`, `live`, `unavailable`),\n- HubSpot field mapping and event schemas,\n- KOOB launch and mapping payloads.\n\n## Integration notes\n\n### HubSpot\n\nEasia Hub reads partner context from HubSpot contacts when live credentials are configured, and otherwise falls back to local fixture partner records. The HubSpot-facing surface also documents the expected custom contact fields and the behavioral-event schema that the Hub emits.\n\n### KOOB\n\nEasia Hub exposes KOOB product mappings and generates signed launch URLs per partner and product. The KOOB documentation here reflects the implemented handoff contract in this codebase, including validation status returned by the Hub, because the downstream KOOB launch confirmation is environment-dependent.\n"},"servers":[{"url":"/","description":"Current deployment origin"}],"tags":[{"name":"System","description":"Health and system-level utility operations for runtime checks and smoke validation."},{"name":"Auth","description":"Session lifecycle endpoints for signed partner identity and viewer-context resolution."},{"name":"Media","description":"Easia Hub media-reference and audit endpoints, including access-filtered asset metadata and integration state."},{"name":"Analytics","description":"First-party Hub analytics capture and reporting operations."},{"name":"Partners","description":"HubSpot-backed partner-directory documentation.\n\nThese operations document the implemented HubSpot integration in Easia Hub, including:\n\n- expected custom contact field mapping,\n- partner fallback behavior when HubSpot is not configured or is degraded,\n- behavioral-event schema used by the Hub analytics bridge.\n","externalDocs":{"description":"HubSpot CRM contacts developer guide","url":"https://developers.hubspot.com/docs/api-reference/crm-contacts-v3/guide"}},{"name":"Booking","description":"KOOB integration operations for mapped products and signed launch handoff.\n\nThese operations document the KOOB contract implemented by Easia Hub, including:\n\n- product-to-shared-ID mappings,\n- partner-scoped signed launch URLs,\n- validation state for the current KOOB environment.\n"},{"name":"Access Control","description":"Viewer audience and market-access context resolved from the signed Hub cookies."}],"paths":{"/api/v1/health":{"get":{"operationId":"getHealth","summary":"Check API health","description":"Returns service health for deployment and CI smoke checks.","tags":["System"],"responses":{"200":{"description":"API is available.","content":{"application/json":{"schema":{"type":"object","required":["status","service"],"properties":{"status":{"type":"string","enum":["ok"]},"service":{"type":"string","enum":["easia-hub-api"]}}}}}}}}},"/api/v1/auth/session":{"get":{"operationId":"getSession","summary":"Get the current session and viewer context","description":"Returns the signed viewer context and partner session for the current request, including partner profile and Canto portal URL.","tags":["Auth"],"responses":{"200":{"description":"Current session state.","content":{"application/json":{"schema":{"type":"object","required":["partnerId","viewer"],"properties":{"partnerId":{"type":"string"},"viewer":{"$ref":"#/components/schemas/ViewerContext"},"currentPartner":{"$ref":"#/components/schemas/PartnerProfile"},"cantoPortalUrl":{"type":"string","nullable":true}}}}}}}},"post":{"operationId":"createSession","summary":"Create a new partner session","description":"Creates a signed partner session by partner ID and returns viewer context with session cookies.","tags":["Auth"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"partnerId":{"type":"string"}}}}}},"responses":{"200":{"description":"Session created successfully.","content":{"application/json":{"schema":{"type":"object","required":["partnerId","viewer"],"properties":{"partnerId":{"type":"string"},"viewer":{"$ref":"#/components/schemas/ViewerContext"}}}}}},"400":{"description":"Invalid session request."},"500":{"description":"Viewer context secret is not configured."}}}},"/api/v1/auth/logout":{"post":{"operationId":"logoutSession","summary":"Clear active partner and viewer sessions","description":"Clears the partner-session and viewer-context cookies, ending the authenticated session.","tags":["Auth"],"responses":{"200":{"description":"Session cookies cleared.","content":{"application/json":{"schema":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean","enum":[true]}}}}}}}}},"/api/v1/media/references":{"get":{"operationId":"listMediaReferences","summary":"List approved media references","description":"Returns access-filtered approved media references for the current viewer, optionally scoped to a destination or product list.","tags":["Media"],"parameters":[{"name":"destination","in":"query","required":false,"schema":{"type":"string"},"description":"Filter to a specific destination slug."},{"name":"products","in":"query","required":false,"schema":{"type":"string"},"description":"Comma-separated product slugs to scope references."}],"responses":{"200":{"description":"Approved media references and integration state.","content":{"application/json":{"schema":{"type":"object","required":["assets","integration"],"properties":{"assets":{"type":"array","items":{"$ref":"#/components/schemas/MediaAsset"}},"integration":{"$ref":"#/components/schemas/IntegrationState"}}}}}}}}},"/api/v1/analytics":{"get":{"operationId":"listAnalyticsEvents","summary":"List recorded Hub analytics events","description":"Returns recorded analytics events and market-segmented usage summaries for Drop 1 reporting. Requires an internal viewer context.","tags":["Analytics"],"parameters":[{"name":"market","in":"query","required":false,"schema":{"type":"string"},"description":"Restrict results to a single market (checks if market is in the event's markets array)."},{"name":"type","in":"query","required":false,"schema":{"$ref":"#/components/schemas/AnalyticsEventType"},"description":"Restrict results to one event type."},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["json","csv"]},"description":"Return JSON summaries or a CSV export of the filtered events."}],"responses":{"200":{"description":"Analytics events and market or partner summaries.","content":{"application/json":{"schema":{"type":"object","required":["events","usageByMarket","usageByPartner"],"properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsEvent"}},"usageByMarket":{"type":"array","items":{"$ref":"#/components/schemas/MarketUsageSummary"}},"usageByPartner":{"type":"array","items":{"$ref":"#/components/schemas/PartnerUsageSummary"}}}}},"text/csv":{"schema":{"type":"string"}}}},"403":{"description":"Analytics reads are restricted to internal viewers."}}},"post":{"operationId":"recordAnalyticsEvent","summary":"Record Hub analytics activity","description":"Records baseline Hub activity including page views, searches, downloads, logins, and regional market context.","tags":["Analytics"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsEventInput"}}}},"responses":{"201":{"description":"Analytics event recorded.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsEvent"}}}},"400":{"description":"Analytics event input is invalid.","content":{"application/json":{"schema":{"type":"object","required":["error"],"properties":{"error":{"type":"string"}}}}}}}}},"/api/v1/canto/rights-audit":{"get":{"operationId":"cantoRightsAudit","summary":"Audit Canto media asset rights","description":"Returns usage rights information for all Canto-synchronized media assets; used for Drop 1 contract evidence.","tags":["Media"],"responses":{"200":{"description":"Rights audit data for Canto assets.","content":{"application/json":{"schema":{"type":"object","required":["sourceSystem","auditedAssets"],"properties":{"sourceSystem":{"type":"string","enum":["Canto DAM"]},"auditedAssets":{"type":"array","items":{"type":"object"}}}}}}}}}},"/api/v1/drop-1/ownership":{"get":{"operationId":"getOwnershipAssignments","summary":"Get content ownership assignments","description":"Returns hardcoded content ownership metadata for Drop 1 contract evidence; scope types include section, destination, product-category, media-library, and integration.","tags":["Governance"],"responses":{"200":{"description":"Content ownership assignments.","content":{"application/json":{"schema":{"type":"object","required":["assignments"],"properties":{"assignments":{"type":"array","items":{"type":"object"}}}}}}}}}},"/api/v1/drop-1/readiness":{"get":{"operationId":"getReadinessCheck","summary":"Get Drop 1 Tier 1 readiness status","description":"Returns Tier 1 readiness status and sign-off for configured markets.","tags":["Governance"],"responses":{"200":{"description":"Tier 1 readiness check data.","content":{"application/json":{"schema":{"type":"object","required":["tier1Readiness"],"properties":{"tier1Readiness":{"type":"array","items":{"type":"object"}}}}}}}}}},"/api/v1/hubspot/partners":{"get":{"operationId":"listPartners","summary":"List partner directory","description":"Returns partner profiles resolved from HubSpot or local fixtures, including contact, audience, and market information.","tags":["Partners"],"responses":{"200":{"description":"Partner directory.","content":{"application/json":{"schema":{"type":"object","required":["partners","integration"],"properties":{"partners":{"type":"array","items":{"type":"object"}},"integration":{"$ref":"#/components/schemas/IntegrationState"}}}}}},"500":{"description":"Failed to fetch partners."}}}},"/api/v1/koob/launch":{"get":{"operationId":"generateLaunchUrl","summary":"Generate a signed KOOB deep-link","description":"Generates a signed deep-link for launching a specific product within KOOB for the current partner.","tags":["Booking"],"parameters":[{"name":"product","in":"query","required":true,"schema":{"type":"string"},"description":"KOOB product ID to launch."}],"responses":{"200":{"description":"Signed launch URL generated.","content":{"application/json":{"schema":{"type":"object","required":["launchUrl","integration"],"properties":{"launchUrl":{"type":"string"},"integration":{"$ref":"#/components/schemas/IntegrationState"}}}}}},"400":{"description":"Missing product parameter."}}}},"/api/v1/koob/products":{"get":{"operationId":"listKoobProducts","summary":"List KOOB-bookable products","description":"Returns products available for booking via KOOB with their mapped product IDs.","tags":["Booking"],"responses":{"200":{"description":"Available KOOB products.","content":{"application/json":{"schema":{"type":"object","required":["products","integration"],"properties":{"products":{"type":"array","items":{"type":"object"}},"integration":{"$ref":"#/components/schemas/IntegrationState"}}}}}}}}},"/api/v1/viewer-context":{"get":{"operationId":"getViewerContext","summary":"Get the current viewer context","description":"Returns the current viewer's audience level and market access from the signed viewer-context cookie.","tags":["Access Control"],"responses":{"200":{"description":"Current viewer context.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ViewerContext"}}}}}}}},"components":{"schemas":{"ViewerContext":{"type":"object","required":["audience","markets"],"properties":{"audience":{"$ref":"#/components/schemas/Audience"},"markets":{"type":"array","items":{"type":"string"}}}},"PartnerProfile":{"type":"object","required":["id","name","role","company","audience","markets"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string"},"company":{"type":"string"},"audience":{"$ref":"#/components/schemas/Audience"},"markets":{"type":"array","items":{"type":"string"}}}},"AnalyticsEventType":{"type":"string","enum":["page_view","search","download","login","copy_link","language_switch"]},"Audience":{"type":"string","enum":["public","agent","internal"]},"AnalyticsEventInput":{"type":"object","required":["type"],"properties":{"type":{"$ref":"#/components/schemas/AnalyticsEventType"},"markets":{"type":"array","items":{"type":"string"},"minItems":1,"description":"Optional; resolved from the signed viewer-context session when omitted."},"partnerId":{"type":"string","description":"Optional; resolved from the signed partner-session cookie when omitted."},"audience":{"$ref":"#/components/schemas/Audience"},"target":{"type":"string"},"source":{"type":"string"}}},"AnalyticsEvent":{"allOf":[{"$ref":"#/components/schemas/AnalyticsEventInput"},{"type":"object","required":["id","timestamp","partnerId"],"properties":{"id":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"partnerId":{"type":"string"}}}]},"MarketUsageSummary":{"type":"object","required":["market","totalEvents","eventsByType"],"properties":{"market":{"type":"string"},"totalEvents":{"type":"integer","minimum":0},"eventsByType":{"type":"object","additionalProperties":{"type":"integer","minimum":0}}}},"PartnerUsageSummary":{"type":"object","required":["partnerId","totalEvents","markets","eventsByType"],"properties":{"partnerId":{"type":"string"},"totalEvents":{"type":"integer","minimum":0},"markets":{"type":"array","items":{"type":"string"}},"eventsByType":{"type":"object","additionalProperties":{"type":"integer","minimum":0}}}},"IntegrationMode":{"type":"string","enum":["fixture","live","unavailable"]},"IntegrationState":{"type":"object","required":["provider","mode","configured","label","detail"],"properties":{"provider":{"type":"string","enum":["canto","hubspot","koob"]},"mode":{"$ref":"#/components/schemas/IntegrationMode"},"configured":{"type":"boolean"},"label":{"type":"string"},"detail":{"type":"string"},"error":{"type":"string"}}},"MediaAssetType":{"type":"string","enum":["image","video"]},"MediaApprovalStatus":{"type":"string","enum":["approved","pending","archived"]},"MediaRights":{"type":"string","enum":["free-to-share","internal-only","requires-attribution"]},"MediaAsset":{"type":"object","required":["id","title","type","approvalStatus","rights","previewLabel","downloadUrl","shareUrl","approvedVersion","latestApprovedVersion","syncedAt","lastUpdated","owner","reviewer","canDownload","canCopyLink","isOfficial","destinationSlugs","productSlugs","audience","markets"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"type":{"$ref":"#/components/schemas/MediaAssetType"},"approvalStatus":{"$ref":"#/components/schemas/MediaApprovalStatus"},"rights":{"$ref":"#/components/schemas/MediaRights"},"previewUrl":{"type":"string"},"previewLabel":{"type":"string"},"downloadUrl":{"type":"string"},"shareUrl":{"type":"string"},"approvedVersion":{"type":"string"},"latestApprovedVersion":{"type":"string"},"syncedAt":{"type":"string","format":"date"},"lastUpdated":{"type":"string","format":"date"},"owner":{"type":"string"},"reviewer":{"type":"string"},"canDownload":{"type":"boolean"},"canCopyLink":{"type":"boolean"},"isOfficial":{"type":"boolean"},"destinationSlugs":{"type":"array","items":{"type":"string"}},"productSlugs":{"type":"array","items":{"type":"string"}},"audience":{"$ref":"#/components/schemas/Audience"},"markets":{"type":"array","items":{"type":"string"}},"cantoAssetId":{"type":"string"}}}}}}