Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
✱ Stainless preview buildsThis PR will update the kotlin openapi python typescript
|
ba22feb to
af1544d
Compare
Greptile SummaryThis PR introduces comprehensive KYC/KYB verification endpoints: beneficial owner management ( Key issues found:
Confidence Score: 2/5
|
| Filename | Overview |
|---|---|
| openapi/components/schemas/customers/BeneficialOwnerPersonalInfo.yaml | Defines personal info required for a beneficial owner; personalIds is incorrectly typed as a single $ref to PersonalIdentification (an object) instead of an array — this prevents representing multiple ID documents for one person. |
| openapi/components/schemas/customers/BeneficialOwnerPersonalInfoUpdate.yaml | Partial-update variant of personal info; carries the same personalIds single-object typing bug as BeneficialOwnerPersonalInfo.yaml. |
| openapi/paths/verifications/verifications.yaml | Adds POST (submit verification) and GET (list verifications) endpoints; POST /verifications correctly returns the Verification resource with an id, but uses 200 instead of the conventional 201 Created status code for resource creation. |
| openapi/components/schemas/verifications/Verification.yaml | New Verification schema; has id, customerId, verificationStatus, errors, and createdAt in required, but updatedAt — which is defined in properties — is absent from the required array, making it technically optional to schema-strict consumers. |
| openapi/components/schemas/documents/Document.yaml | New Document response schema; missing a status/reviewResult field, updatedAt is not in required, making document review state invisible to clients querying GET /documents. |
| openapi/paths/beneficial-owners/beneficial_owners_{beneficialOwnerId}.yaml | Defines GET and newly added PATCH operations for a specific beneficial owner; PATCH correctly references BeneficialOwnerUpdateRequest which uses the all-optional BeneficialOwnerPersonalInfoUpdate schema for partial updates — good design. |
| openapi/components/schemas/customers/BeneficialOwner.yaml | Beneficial owner response schema; updatedAt is defined in properties but absent from the required array, making it technically optional for schema-strict consumers even though the field is always populated. |
| openapi/components/schemas/webhooks/WebhookType.yaml | Breaking: removes CUSTOMER.KYC_SUBMITTED, CUSTOMER.KYB_SUBMITTED, CUSTOMER.KYC_MANUALLY_APPROVED/REJECTED, and CUSTOMER.KYB_MANUALLY_APPROVED/REJECTED enum values; existing clients subscribed to those event types will silently stop receiving events. |
| openapi/components/schemas/customers/ExpectedActivityVolumes.yaml | Defines expected transaction count/volume enums; several values start with a digit (10_TO_100, 100_TO_500, 10K_TO_100K) which are invalid identifiers in most code-generation target languages and will cause SDK compilation failures. |
| mintlify/snippets/sandbox-kyb-verification.mdx | New sandbox testing snippet for KYC/KYB; document verification result column shows generic REJECTED label but the Document schema doesn't expose a reviewResult/status field at all, so the table describes state that can't currently be observed via the API. |
Sequence Diagram
sequenceDiagram
participant C as Client
participant API as Grid API
participant WH as Client Webhook
C->>API: POST /customers (business)
API-->>C: 201 Customer {id, kybStatus: UNVERIFIED}
C->>API: POST /beneficial-owners
API-->>C: 201 BeneficialOwner {id, kycStatus: PENDING}
C->>API: POST /documents (multipart/form-data)
API-->>C: 201 Document {id, documentType, ...}
C->>API: POST /verifications {customerId}
alt Missing information
API-->>C: 200 Verification {verificationStatus: RESOLVE_ERRORS, errors: [...]}
C->>API: PATCH /customers/{id} (fix missing fields)
C->>API: PUT /documents/{documentId} (replace rejected doc)
C->>API: POST /verifications {customerId} (re-submit)
end
API-->>C: 200 Verification {verificationStatus: IN_PROGRESS, errors: []}
API->>WH: POST webhook {type: VERIFICATION.APPROVED}
WH-->>API: 200 OK
Note over C,API: Customer kybStatus → APPROVED
Prompt To Fix All With AI
This is a comment left during a code review.
Path: openapi/components/schemas/customers/BeneficialOwnerPersonalInfo.yaml
Line: 43-44
Comment:
**`personalIds` typed as single object instead of array**
`personalIds` resolves to the `PersonalIdentification` schema directly — which is `type: object` — meaning the field accepts exactly **one** identification document, not a list. The plural name `personalIds` and the KYB domain context (many jurisdictions require collecting both a government-issued ID *and* a secondary ID such as a tax number) strongly indicate this was intended to be an array.
As it stands, a beneficial owner with two forms of ID (e.g., passport + SSN) cannot be represented. The field should be declared as:
```suggestion
personalIds:
type: array
items:
$ref: ./PersonalIdentification.yaml
```
The same fix is needed in `BeneficialOwnerPersonalInfoUpdate.yaml` line 38.
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: openapi/components/schemas/customers/BeneficialOwnerPersonalInfoUpdate.yaml
Line: 37-38
Comment:
**`personalIds` typed as single object instead of array**
Same issue as in `BeneficialOwnerPersonalInfo.yaml` — `personalIds` directly `$ref`s the `PersonalIdentification` schema (a single object) rather than defining it as an array of identifications. This should be:
```suggestion
personalIds:
type: array
items:
$ref: ./PersonalIdentification.yaml
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: openapi/webhooks/verification-update.yaml
Line: 50-51
Comment:
**Webhook examples missing `updatedAt` field**
The `Verification` schema defines `updatedAt` in its `properties`, and real server responses will include it. Both the `approved` and `resolveErrors` webhook examples omit `updatedAt` from the embedded `Verification` data object. This makes the examples inconsistent with the schema and may confuse integrators who read them to understand the payload shape.
Consider adding `updatedAt` to both examples, e.g.:
```yaml
createdAt: '2025-08-15T14:00:00Z'
updatedAt: '2025-08-15T14:32:00Z'
```
The same omission exists in the inline examples inside `openapi/paths/verifications/verifications.yaml` (lines 54 and 62).
How can I resolve this? If you propose a fix, please make it concise.Last reviewed commit: "feat: adding kyb sch..."
openapi/components/schemas/verifications/VerificationStatus.yaml
Outdated
Show resolved
Hide resolved
openapi/paths/beneficial-owners/beneficial_owners_{beneficialOwnerId}.yaml
Show resolved
Hide resolved
af1544d to
3ed8713
Compare
3ed8713 to
511e2de
Compare
511e2de to
6e4f7df
Compare
6e4f7df to
01ddcc3
Compare
01ddcc3 to
94498a6
Compare
94498a6 to
127e554
Compare
127e554 to
2e1a718
Compare
openapi/components/schemas/verifications/VerificationError.yaml
Outdated
Show resolved
Hide resolved
| - BENEFICIAL_OWNER.KYC_MANUALLY_APPROVED | ||
| - BENEFICIAL_OWNER.KYC_MANUALLY_REJECTED |
There was a problem hiding this comment.
Not sure if we need this level of precision
| - VERIFICATION.IN_PROGRESS | ||
| - VERIFICATION.PENDING_MANUAL_REVIEW |
There was a problem hiding this comment.
I think just IN_PROGRESS will be fine
1ed3cc7 to
723fc81
Compare
723fc81 to
bec1798
Compare
bec1798 to
bf85b0f
Compare
openapi/components/schemas/customers/BeneficialOwnerUpdateRequest.yaml
Outdated
Show resolved
Hide resolved
bf85b0f to
8ae286c
Compare
| type: string | ||
| enum: | ||
| - AWAITING_SUBMISSION | ||
| - UNVERIFIED |
There was a problem hiding this comment.
Is PENDING sufficient? Is unverified meant to be unsubmitted basically?
| pattern: '^\+[1-9]\d{1,14}$' | ||
| address: | ||
| $ref: ../common/Address.yaml | ||
| personalIds: |
There was a problem hiding this comment.
Can we remove this for now? I think we get this automatically with personal identification document being a hard requirement for all UBOs
| Dot-notation path to the field with the issue. Present when type is | ||
| MISSING_FIELD or INVALID_FIELD. | ||
| example: customer.address.line1 | ||
| documentType: |
There was a problem hiding this comment.
I think documentType might need to return a list of documentTypes for instances where we accept oneOf a set e.g. [DRIVERS, PASSPORT]
There was a problem hiding this comment.
I thought you would return one error for each document issue?
There was a problem hiding this comment.
How do we indicate to users that we are missing oneOf a set of acceptable documents. Let's say for UBOs, we can take either a DRIVERS or a PASSPORT. Would it be confusing if we have two separate MISSING_DOCUMENT objects?
There was a problem hiding this comment.
I see what you're saying
8ae286c to
5ff69d5
Compare
| personalIds: | ||
| $ref: ./PersonalIdentification.yaml |
There was a problem hiding this comment.
personalIds typed as single object instead of array
personalIds resolves to the PersonalIdentification schema directly — which is type: object — meaning the field accepts exactly one identification document, not a list. The plural name personalIds and the KYB domain context (many jurisdictions require collecting both a government-issued ID and a secondary ID such as a tax number) strongly indicate this was intended to be an array.
As it stands, a beneficial owner with two forms of ID (e.g., passport + SSN) cannot be represented. The field should be declared as:
| personalIds: | |
| $ref: ./PersonalIdentification.yaml | |
| personalIds: | |
| type: array | |
| items: | |
| $ref: ./PersonalIdentification.yaml |
The same fix is needed in BeneficialOwnerPersonalInfoUpdate.yaml line 38.
Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/customers/BeneficialOwnerPersonalInfo.yaml
Line: 43-44
Comment:
**`personalIds` typed as single object instead of array**
`personalIds` resolves to the `PersonalIdentification` schema directly — which is `type: object` — meaning the field accepts exactly **one** identification document, not a list. The plural name `personalIds` and the KYB domain context (many jurisdictions require collecting both a government-issued ID *and* a secondary ID such as a tax number) strongly indicate this was intended to be an array.
As it stands, a beneficial owner with two forms of ID (e.g., passport + SSN) cannot be represented. The field should be declared as:
```suggestion
personalIds:
type: array
items:
$ref: ./PersonalIdentification.yaml
```
The same fix is needed in `BeneficialOwnerPersonalInfoUpdate.yaml` line 38.
How can I resolve this? If you propose a fix, please make it concise.| personalIds: | ||
| $ref: ./PersonalIdentification.yaml |
There was a problem hiding this comment.
personalIds typed as single object instead of array
Same issue as in BeneficialOwnerPersonalInfo.yaml — personalIds directly $refs the PersonalIdentification schema (a single object) rather than defining it as an array of identifications. This should be:
| personalIds: | |
| $ref: ./PersonalIdentification.yaml | |
| personalIds: | |
| type: array | |
| items: | |
| $ref: ./PersonalIdentification.yaml |
Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/components/schemas/customers/BeneficialOwnerPersonalInfoUpdate.yaml
Line: 37-38
Comment:
**`personalIds` typed as single object instead of array**
Same issue as in `BeneficialOwnerPersonalInfo.yaml` — `personalIds` directly `$ref`s the `PersonalIdentification` schema (a single object) rather than defining it as an array of identifications. This should be:
```suggestion
personalIds:
type: array
items:
$ref: ./PersonalIdentification.yaml
```
How can I resolve this? If you propose a fix, please make it concise.| errors: [] | ||
| createdAt: '2025-08-15T14:00:00Z' |
There was a problem hiding this comment.
Webhook examples missing
updatedAt field
The Verification schema defines updatedAt in its properties, and real server responses will include it. Both the approved and resolveErrors webhook examples omit updatedAt from the embedded Verification data object. This makes the examples inconsistent with the schema and may confuse integrators who read them to understand the payload shape.
Consider adding updatedAt to both examples, e.g.:
createdAt: '2025-08-15T14:00:00Z'
updatedAt: '2025-08-15T14:32:00Z'The same omission exists in the inline examples inside openapi/paths/verifications/verifications.yaml (lines 54 and 62).
Prompt To Fix With AI
This is a comment left during a code review.
Path: openapi/webhooks/verification-update.yaml
Line: 50-51
Comment:
**Webhook examples missing `updatedAt` field**
The `Verification` schema defines `updatedAt` in its `properties`, and real server responses will include it. Both the `approved` and `resolveErrors` webhook examples omit `updatedAt` from the embedded `Verification` data object. This makes the examples inconsistent with the schema and may confuse integrators who read them to understand the payload shape.
Consider adding `updatedAt` to both examples, e.g.:
```yaml
createdAt: '2025-08-15T14:00:00Z'
updatedAt: '2025-08-15T14:32:00Z'
```
The same omission exists in the inline examples inside `openapi/paths/verifications/verifications.yaml` (lines 54 and 62).
How can I resolve this? If you propose a fix, please make it concise.
TL;DR
Added comprehensive KYC/KYB verification endpoints including beneficial owner management, document upload capabilities, and verification workflow APIs.
What changed?
Added three new API endpoint groups:
Beneficial Owners API:
POST /beneficial-owners- Create beneficial owners, directors, and company officers for business customersGET /beneficial-owners- List beneficial owners with filtering by customer ID and roleGET /beneficial-owners/{beneficialOwnerId}- Retrieve specific beneficial owner detailsDocuments API:
POST /documents- Upload verification documents (PDF, JPEG, PNG up to 10MB) with multipart/form-dataGET /documents- List documents with filtering by holder, type, and statusGET /documents/{documentId}- Retrieve document metadataPUT /documents/{documentId}- Replace existing documentsDELETE /documents/{documentId}- Delete documents (with conflict handling for submitted docs)Verifications API:
POST /verifications- Submit customers for KYC/KYB verification with detailed error reportingEnhanced business customer schemas with additional fields including entity type, business type, incorporation details, expected activity volumes, and compliance information.
How to test?
Why make this change?
Enables comprehensive KYC/KYB compliance workflows by providing APIs to manage all required verification data including beneficial ownership information, document uploads, and verification status tracking with actionable error messages.