openapi: 3.0.3 info: version: v1.0.0 title: LE-KO KYC license: name: private url: https://le-ko.deggex.com contact: email: denis@deggex.awsapps.com description: LE-KO Know Your Customer (KYC) verification API for identity verification, document processing, and compliance management. servers: - url: https://kyc-{env}.le-ko.deggex.com/{basePath} description: KYC endpoint variables: basePath: default: v1 env: default: dev security: - bearerHttpAuthentication: [] tags: - name: kyc description: KYC verification paths: /verifications: post: tags: - kyc summary: verifications description: ✨ Initiates a new KYC verification process for a coach operationId: createVerification parameters: - $ref: '#/components/parameters/CurrentUserId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/VerificationCreate' responses: '201': description: Verification created successfully content: application/json: schema: $ref: '#/components/schemas/Verification' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/Errors' '409': description: Active Verification already exists for this coach content: application/json: schema: $ref: '#/components/schemas/Errors' get: tags: - kyc summary: verifications description: ✨ List all KYC verifications operationId: listVerifications parameters: - $ref: '#/components/parameters/CurrentUserId' - $ref: '#/components/parameters/Number' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/CoachId' responses: '200': description: List of verifications content: application/json: schema: $ref: '#/components/schemas/VerificationsPage' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/Errors' /verifications/{verificationId}: get: tags: - kyc summary: verifications/{id} description: ✨ Retrieve details of a specific KYC verification operationId: getVerification parameters: - $ref: '#/components/parameters/CurrentUserId' - name: verificationId in: path required: true schema: $ref: '#/components/schemas/VerificationId' description: ID of the verification to retrieve responses: '200': description: Verification details retrieved successfully content: application/json: schema: $ref: '#/components/schemas/Verification' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/Errors' put: tags: - kyc summary: verifications/{id} description: ✨ Update a specific KYC passport data operationId: updatePassportData parameters: - $ref: '#/components/parameters/CurrentUserId' - name: verificationId in: path required: true schema: $ref: '#/components/schemas/VerificationId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PassportData' responses: '204': description: Passport data updated successfully '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/Errors' /verifications/{verificationId}/avatar: post: tags: - kyc summary: verifications/{id}/avatar description: ✨ Upload an avatar image to verify it contains a human face operationId: uploadAvatar parameters: - $ref: '#/components/parameters/CurrentUserId' - name: verificationId in: path required: true schema: $ref: '#/components/schemas/VerificationId' description: ID of the verification requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AvatarVerificationRequest' responses: '200': description: Avatar uploaded and verification started content: application/json: schema: $ref: '#/components/schemas/Verification' '400': description: Bad request - invalid file format or size content: application/json: schema: $ref: '#/components/schemas/Errors' '409': description: Avatar already uploaded for this verification content: application/json: schema: $ref: '#/components/schemas/Errors' /verifications/{verificationId}/passport: post: tags: - kyc summary: verifications/{id}/passport description: ✨ Upload a passport image for OCR text extraction and verification operationId: uploadPassport parameters: - $ref: '#/components/parameters/CurrentUserId' - name: verificationId in: path required: true schema: $ref: '#/components/schemas/VerificationId' description: ID of the verification requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/PassportVerificationRequest' responses: '200': description: Passport uploaded and OCR processing started content: application/json: schema: $ref: '#/components/schemas/Verification' '400': description: Bad request - invalid file format or size content: application/json: schema: $ref: '#/components/schemas/Errors' '409': description: Passport already uploaded for this verification content: application/json: schema: $ref: '#/components/schemas/Errors' /verifications/status: get: tags: - kyc summary: verifications/status description: ✨ Get the current status and progress of a recent KYC verification for the current user operationId: getVerificationStatus parameters: - $ref: '#/components/parameters/CurrentUserId' responses: '200': description: Verification status retrieved successfully content: application/json: schema: $ref: '#/components/schemas/VerificationStatus' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/Errors' /verifications/{verificationId}/admin: put: tags: - kyc summary: verifications/{id}/admin description: ✨ Admin endpoint to approve or reject a KYC verification operationId: adminManageVerification parameters: - $ref: '#/components/parameters/CurrentUserId' - name: verificationId in: path required: true schema: $ref: '#/components/schemas/VerificationId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AdminApproval' responses: '200': description: Verification status updated successfully content: application/json: schema: $ref: '#/components/schemas/VerificationStatus' '400': description: Bad request content: application/json: schema: $ref: '#/components/schemas/Errors' '409': description: Conflict - Verification must be in admin_review_required status content: application/json: schema: $ref: '#/components/schemas/Errors' components: securitySchemes: bearerHttpAuthentication: description: Bearer token using a JWT type: http scheme: bearer bearerFormat: JWT parameters: CurrentUserId: name: x-current-user-id in: header required: true schema: type: string format: uuid Number: name: number required: false in: query schema: $ref: '#/components/schemas/PageNumber' Limit: name: limit required: false in: query schema: $ref: '#/components/schemas/Limit' CoachId: name: coachId required: false in: query schema: $ref: '#/components/schemas/CoachId' schemas: PageNumber: type: integer description: Page number example: 0 minimum: 0 default: 0 Limit: type: integer description: Page limit default: 10 minimum: 1 maximum: 100 example: 10 CoachId: type: string example: 00000000-0000-1000-9000-510d9bb07630 description: Coach ID format: uuid Count: type: integer description: Page entries count example: 10 Total: type: integer description: Total count default: 0 minimum: 0 example: 1000 Page: type: object required: - count - page - limit - total properties: data: type: array items: type: object count: $ref: '#/components/schemas/Count' page: $ref: '#/components/schemas/PageNumber' limit: $ref: '#/components/schemas/Limit' total: $ref: '#/components/schemas/Total' VerificationId: type: string example: 00000000-0000-1000-9000-55f01dda9dd0 description: KYC verification ID format: uuid Status: type: string description: Current status of the KYC verification process enum: - pending - avatar_verified - passport_verified - approved - rejected - admin_review_required example: pending VerificationStep: type: string description: Current step in the KYC verification process enum: - initialize - avatar_verification - passport_verification - image_matching - admin_review - completed example: avatar_verification DateTime: type: string format: date-time description: Date and time in RFC-3339 example: '2024-11-29T12:09:53+00:00' AvatarVerification: type: object required: - isHuman - processedAt properties: isHuman: type: boolean description: Whether the avatar image contains a human face processedAt: $ref: '#/components/schemas/DateTime' errorMessage: type: string description: Error message if verification failed example: isHuman: true processedAt: '2024-01-15T10:30:00Z' PassportFirstName: type: string example: John description: First name exactly as in the passport format: string PassportLastName: type: string example: Doe description: Last name exactly as in the passport format: string PassportDoB: type: string format: date description: Date of birth exactly as in the passport in RFC-3339 format (YYYY-MM-DD) example: '2024-11-29' Date: type: string format: date description: Date in RFC-3339 format (YYYY-MM-DD) example: '2024-11-29' PassportData: type: object required: - firstName - lastName - passportNumber - dateOfBirth - issuedDate - placeOfBirth - middleName - subdivision properties: firstName: $ref: '#/components/schemas/PassportFirstName' lastName: $ref: '#/components/schemas/PassportLastName' passportNumber: type: string description: Passport number extracted from passport example: '6013453434' dateOfBirth: $ref: '#/components/schemas/PassportDoB' issuedDate: $ref: '#/components/schemas/Date' placeOfBirth: type: string description: Place of birth if available example: New York, USA middleName: type: string description: Middle name if available example: James subdivision: type: string description: Subdivision if available example: NY example: firstName: John lastName: Doe passportNumber: A1234567 dateOfBirth: '1990-01-15' issuedDate: '2030-01-15' placeOfBirth: New York, USA middleName: James subdivision: NY PassportVerification: type: object required: - ocrSuccess - processedAt properties: ocrSuccess: type: boolean description: Whether OCR processing was successful passportData: $ref: '#/components/schemas/PassportData' description: Extracted passport data (only present if ocrSuccess is true) processedAt: $ref: '#/components/schemas/DateTime' errorMessage: type: string description: Error message if OCR failed confidence: type: number format: float minimum: 0 maximum: 1 description: Confidence score for OCR accuracy (0-1) example: ocrSuccess: true passportData: firstName: John lastName: Doe passportNumber: A1234567 dateOfBirth: '1990-01-15' issuedDate: '2030-01-15' placeOfBirth: New York, USA middleName: James subdivision: NY processedAt: '2024-01-15T10:35:00Z' confidence: 0.92 ImageMatchResult: type: object required: - isMatched - processedAt properties: isMatched: type: boolean description: Whether the images are considered a match based on threshold processedAt: $ref: '#/components/schemas/DateTime' errorMessage: type: string description: Error message if matching failed example: isMatched: true processedAt: '2024-01-15T10:40:00Z' VerificationFailure: type: object required: - step - reason - occurredAt properties: step: $ref: '#/components/schemas/VerificationStep' description: The step where the failure occurred reason: type: string description: Reason for the failure enum: - avatar_not_human - passport_ocr_failed - passport_invalid_format - images_no_match - image_processing_error - admin_review_required - system_error occurredAt: $ref: '#/components/schemas/DateTime' details: type: string description: Additional details about the failure retryable: type: boolean description: Whether the verification can be retried default: false example: step: image_matching reason: images_no_match occurredAt: '2024-01-15T10:40:00Z' details: Match score 0.45 is below threshold 0.8 retryable: true AdminApproval: type: object required: - approved properties: approved: type: boolean description: Whether the verification is approved reason: type: string description: Reason for rejection enum: - document_unclear - identity_mismatch - fake_document - insufficient_quality - inappropriate_content notes: type: string description: Optional notes for the approval maxLength: 500 reviewerId: type: string description: ID of the admin who approved example: admin-123 example: approved: true notes: All documents verified successfully reviewerId: admin-123 Verification: type: object required: - id - coachId - status - currentStep - createdAt - updatedAt properties: id: $ref: '#/components/schemas/VerificationId' coachId: $ref: '#/components/schemas/CoachId' status: $ref: '#/components/schemas/Status' currentStep: $ref: '#/components/schemas/VerificationStep' avatarVerification: $ref: '#/components/schemas/AvatarVerification' passportVerification: $ref: '#/components/schemas/PassportVerification' imageMatchResult: $ref: '#/components/schemas/ImageMatchResult' failureReason: $ref: '#/components/schemas/VerificationFailure' adminApproval: $ref: '#/components/schemas/AdminApproval' notes: type: string description: Additional notes or comments createdAt: $ref: '#/components/schemas/DateTime' updatedAt: $ref: '#/components/schemas/DateTime' completedAt: $ref: '#/components/schemas/DateTime' example: id: 00000000-0000-1000-9000-55f01dda9dd0 coachId: 00000000-0000-1000-9000-55f01dda9dd0 status: pending currentStep: passport_verification avatarVerification: isHuman: true confidence: 0.95 processedAt: '2024-01-15T10:30:00Z' passportVerification: ocrSuccess: true passportData: firstName: John lastName: Doe passportNumber: A1234567 dateOfBirth: '1990-01-15' issuedDate: '2030-01-15' placeOfBirth: New York, USA middleName: James subdivision: NY processedAt: '2024-01-15T10:35:00Z' imageMatchResult: matchScore: 0.87 isMatched: true processedAt: '2024-01-15T10:40:00Z' createdAt: '2024-01-15T10:00:00Z' updatedAt: '2024-01-15T10:40:00Z' VerificationsPage: type: object allOf: - $ref: '#/components/schemas/Page' - type: object properties: data: type: array items: $ref: '#/components/schemas/Verification' Error: type: object required: - code - message - endpoint - requestId properties: code: type: string description: Error unique code enum: - validation - internal - oops - unexpected - tooManyRequests - notFound - unauthorized - forbidden message: type: string description: Error message endpoint: type: string requestId: type: string Errors: type: object required: - errors properties: errors: type: array items: $ref: '#/components/schemas/Error' VerificationCreate: type: object properties: notes: type: string description: Optional notes for the verification request maxLength: 500 example: notes: Initial KYC verification request AvatarFileKey: type: string example: some-key description: Key to avatar image bytes in S3 AvatarVerificationRequest: type: object required: - fileKey properties: fileKey: $ref: '#/components/schemas/AvatarFileKey' example: fileKey: some-key PassportFileKey: type: string example: some-key description: Key to passport image bytes in S3 PassportVerificationRequest: type: object required: - fileKey properties: fileKey: $ref: '#/components/schemas/PassportFileKey' description: URL to passport image bytes in JPEG format example: fileKey: some-key AvatarVerified: type: object properties: success: type: boolean attempts: type: integer PassportVerified: type: object properties: success: type: boolean attempts: type: integer VerificationStatus: type: object required: - id - status - currentStep - progress properties: id: $ref: '#/components/schemas/VerificationId' status: $ref: '#/components/schemas/Status' currentStep: $ref: '#/components/schemas/VerificationStep' progress: type: object required: - avatarVerified - passportVerified - imagesMatched properties: avatarVerified: $ref: '#/components/schemas/AvatarVerified' passportVerified: $ref: '#/components/schemas/PassportVerified' imagesMatched: type: boolean description: Whether image matching is complete nextStep: $ref: '#/components/schemas/VerificationStep' createdAt: $ref: '#/components/schemas/DateTime' updatedAt: $ref: '#/components/schemas/DateTime'