{"openapi":"3.1.0","info":{"title":"CUE Context API","version":"v1","description":"Context API request and response specification. Provides user identifiers, installation attribution, and purchase and churn predictions. Examples are illustrative."},"servers":[{"url":"https://api.airbridge.io/entry/inference","description":"Production"}],"tags":[{"name":"Context","description":"앱 설치 기여 정보와 D3 purchase 및 churn 예측 API"}],"paths":{"/v1/context":{"post":{"tags":["Context"],"operationId":"predictContext","summary":"앱 설치 기여 정보와 D3 purchase 및 churn 확률과 tier 조회","description":"사용자 식별자로 설치 기여 정보와 앱 설치 시점 기준의 D3 구매 및 이탈 예측 확률과 등급을 조회합니다.\n각 모델의 전체 학습 입력 확률 분포에서 구한 q10~q90로 10개 구간을 나눕니다.\n경계값은 아래 구간에 포함하며 1~3분위는 low, 4~7분위는 medium, 8~10분위는 high입니다.\n확률이 q30과 같으면 low, q70과 같으면 medium이며 중복 경계는 처음 일치한 구간을 사용합니다.\n활성 번들에 두 모델의 유효한 분위수가 없으면 503을 반환합니다.\n저장된 피처가 float32 모델 입력의 유한한 표현 범위를 벗어나면 CONTEXT_FEATURE_INVALID 500을 반환합니다.\n이 오류는 retryable=false이며 데이터 수정 전에는 재시도하지 않습니다.\n","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextRequest"},"example":{"userId":"airbridge-user-id"}}}},"responses":{"200":{"description":"설치 기여 정보, 두 모델의 확률과 tier, 요청 식별자 및 서버 요청 ID","headers":{"X-Request-Id":{"$ref":"#/components/headers/ServerRequestId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContextResponse"},"example":{"requestId":"01915c8e-7a12-7d3f-8b2a-1f2e3d4c5b6a","appId":1234,"user":{"id":"airbridge-user-id","type":"airbridge_generated_uuid"},"context":{"lastTouchpoint":{"channel":"media_A","campaign":"moving_service","adGroup":"moving_quote","adCreative":"moving_guide_video","term":null}},"predictions":{"d3_purchase":{"probability":0.72,"tier":"high"},"d3_churn":{"probability":0.82,"tier":"high"}}}}}},"400":{"description":"INVALID_JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"UNAUTHORIZED","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"CONTEXT_DATA_NOT_FOUND — 식별자 또는 피처 부재","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"CONTEXT_INACTIVE 또는 IDENTIFIER_CONFLICT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"PAYLOAD_TOO_LARGE","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"VALIDATION_ERROR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"CONTEXT_FEATURE_INVALID — 저장된 피처가 float32 모델 입력 범위를 벗어남","headers":{"X-Request-Id":{"$ref":"#/components/headers/ServerRequestId"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"requestId":"01915c8e-7a12-7d3f-8b2a-1f2e3d4c5b6a","error":{"code":"CONTEXT_FEATURE_INVALID","message":"Context model features are invalid.","retryable":false}}}}},"503":{"description":"CONTEXT_UNAVAILABLE, CONTEXT_LOG_UNAVAILABLE 또는 인증 의존성 장애","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Airbridge App Token","description":"Airbridge SDK token 또는 Web token. token 원문은 요청 body에 보내지 않습니다."}},"schemas":{"ContextRequest":{"type":"object","additionalProperties":false,"oneOf":[{"required":["userId"]},{"required":["brazeDeviceId"]},{"required":["airbridgeExternalUserId"]}],"properties":{"userId":{"$ref":"#/components/schemas/UserId"},"brazeDeviceId":{"$ref":"#/components/schemas/BrazeDeviceId"},"airbridgeExternalUserId":{"$ref":"#/components/schemas/AirbridgeExternalId"}}},"UserId":{"type":"string","minLength":1,"pattern":"\\S","description":"Airbridge Generated UUID. 앞뒤 공백을 제거하며 내부 공백은 유지합니다. 공백 제거 후 빈 값은 허용하지 않습니다."},"BrazeDeviceId":{"type":"string","minLength":1,"pattern":"\\S","description":"Braze SDK Device ID. 앞뒤 공백을 제거하며 내부 공백은 유지합니다. 공백 제거 후 빈 값은 허용하지 않습니다."},"AirbridgeExternalId":{"type":"string","minLength":1,"pattern":"\\S","description":"고객사 사용자 ID. 해당 타입의 매핑에서 Generated UUID로 해석하며 UUID 형식을 요구하지 않습니다. 앞뒤 공백을 제거하며 내부 공백은 유지합니다. 공백 제거 후 빈 값은 허용하지 않습니다."},"ServerRequestId":{"type":"string","format":"uuid","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$","description":"서버가 발급한 lowercase UUIDv7"},"ContextResponse":{"type":"object","additionalProperties":false,"required":["requestId","appId","user","context","predictions"],"properties":{"requestId":{"$ref":"#/components/schemas/ServerRequestId"},"appId":{"type":"integer","minimum":1},"user":{"type":"object","additionalProperties":false,"required":["id","type"],"description":"요청에 사용한 식별자의 정규화된 값과 종류. 별칭을 내부 사용자 UUID로 대체하지 않습니다.","properties":{"id":{"type":"string","minLength":1},"type":{"type":"string","enum":["airbridge_generated_uuid","braze_device_id","airbridge_external_user_id"]}}},"context":{"$ref":"#/components/schemas/ContextAttribution"},"predictions":{"type":"object","additionalProperties":false,"required":["d3_purchase","d3_churn"],"description":"모델 이름은 snake_case를 유지하며 그 외 응답 키는 camelCase를 사용합니다.","properties":{"d3_purchase":{"$ref":"#/components/schemas/ContextPrediction"},"d3_churn":{"$ref":"#/components/schemas/ContextPrediction"}}}}},"ContextAttribution":{"type":"object","additionalProperties":false,"required":["lastTouchpoint"],"description":"요청한 사용자 식별자를 통해 확인한 기기의 설치 이벤트에 대한 기여 정보입니다.","properties":{"lastTouchpoint":{"$ref":"#/components/schemas/LastTouchpoint"}}},"LastTouchpoint":{"type":["object","null"],"additionalProperties":false,"required":["channel","campaign","adGroup","adCreative","term"],"description":"설치 이벤트에 기여한 채널과 캠페인 정보입니다. 사용자가 가장 최근에 클릭한 광고나 최근 유입을 뜻하지 않습니다. 조회에 성공했지만 기여 결과가 없으면 객체는 null입니다. 객체가 있으면 다섯 키를 유지하고 개별 값이 없으면 null입니다. restricted와 unattributed는 원본 값을 유지하며 자연 유입으로 단정하지 않습니다. subPublisher는 포함하지 않습니다. 조회 실패를 기여 결과가 없는 상태와 혼동하지 않습니다.","properties":{"channel":{"type":["string","null"],"description":"설치에 기여한 채널입니다. restricted 또는 unattributed 값만으로 자연 유입을 판단하지 않습니다.","example":"media_A"},"campaign":{"type":["string","null"],"description":"설치에 기여한 캠페인입니다.","example":"moving_service"},"adGroup":{"type":["string","null"],"description":"캠페인에 속한 광고 그룹입니다.","example":"moving_quote"},"adCreative":{"type":["string","null"],"description":"설치에 기여한 광고 소재입니다.","example":"moving_guide_video"},"term":{"type":["string","null"],"description":"광고에 설정된 키워드입니다. 사용자가 입력한 실제 검색어를 보장하지 않습니다.","example":null}}},"ContextPrediction":{"type":"object","additionalProperties":false,"required":["probability","tier"],"properties":{"probability":{"type":"number","minimum":0,"maximum":1,"description":"소수점 넷째 자리에서 반올림해 셋째 자리까지 표현한 예측 확률입니다. tier는 반올림 전 확률로 계산합니다."},"tier":{"type":"string","enum":["low","medium","high"],"description":"모델별 확률 분포의 1~3분위 low, 4~7분위 medium, 8~10분위 high. 확률 고정 임계값을 사용하지 않습니다."}}},"ErrorResponse":{"type":"object","description":"모든 실패 body는 `requestId`와 `error.code`, `error.message`, `error.retryable`만\n포함합니다. `error.message`는 안전한 설명이며 클라이언트 분기 기준은 `error.code`입니다.\n","additionalProperties":false,"required":["requestId","error"],"properties":{"requestId":{"$ref":"#/components/schemas/ServerRequestId"},"error":{"$ref":"#/components/schemas/ErrorDetail"}}},"ErrorDetail":{"type":"object","additionalProperties":false,"required":["code","message","retryable"],"properties":{"code":{"$ref":"#/components/schemas/ErrorCode"},"message":{"type":"string","minLength":1,"description":"예외 문자열을 포함하지 않는 안전한 사용자 설명"},"retryable":{"type":"boolean","description":"동일 요청의 자동 재시도 가능 여부. code별로 고정됩니다."}}},"ErrorCode":{"type":"string","enum":["CONTEXT_INACTIVE","CONTEXT_DATA_NOT_FOUND","CONTEXT_UNAVAILABLE","CONTEXT_FEATURE_INVALID","CONTEXT_LOG_UNAVAILABLE","INVALID_JSON","UNAUTHORIZED","NO_ACTIVE_OPTIMIZATION","IDENTIFIER_CONFLICT","REVIEW_TARGET_MISMATCH","PAYLOAD_TOO_LARGE","VALIDATION_ERROR","INTERNAL_ERROR","AUTHENTICATION_UNAVAILABLE","AUTHENTICATION_STATE_INVALID","SERVING_UNAVAILABLE","SERVING_STATE_INVALID","SERVING_TERMINATED"]}},"headers":{"ServerRequestId":{"required":true,"description":"서버가 호출마다 새로 발급한 UUIDv7이며 response body의 `requestId`와 같습니다.","schema":{"$ref":"#/components/schemas/ServerRequestId"}}}},"x-cue-publication":{"status":"published","updated":"2026-10-12"}}