KYC API Frontend Guide
This public course helps frontend teams build regulated onboarding, due diligence, case review, customer refresh, and compliance operations products on top of the KYC API.
The course is written for implementation. It teaches the browser-safe API contract, the screens to build, the product states to handle, and the security boundaries a frontend team must preserve.
The structure is deliberately incremental: each topic has one job, one visible outcome, and a checkpoint before the next topic. You can follow the course from the beginning, or you can enter through the page that matches the screen you are building today.
Who This Is For
- Frontend engineers integrating a KYC or due diligence API.
- Product engineers building onboarding or review workflows.
- Technical leads coaching a team through regulated API integration.
- LLM coding agents that need a precise implementation contract.
What You Will Learn
- How the frontend-facing API capabilities fit together.
- How to configure the API boundary without leaking secrets.
- How to build a typed API client.
- How to add diagnostics before product screens.
- How to treat API errors as product states.
- How to render quick screening evidence.
- How to create and update durable case workspaces.
- How to generate report snapshots.
- How to poll workflow events.
- How to keep recommendations separate from human decisions.
- How to adapt the same integration pattern to banks, fintechs, insurers, marketplaces, lenders, and other regulated products.
How The Course Is Organized
- Course Map gives the recommended learning path.
- Big Picture explains the system model.
- Workflow pages show complete product paths.
- Foundation pages define reusable contracts.
- Task pages build one API-backed feature at a time.
- Quality pages verify accessibility, audit readiness, tests, and launch safety.
Public-Safe Scope
This guide intentionally avoids internal implementation details. It focuses on the public frontend contract: endpoints, request shapes, response states, security rules, and user experience patterns.
For autonomous implementation, see the LLM Coder Agent Contract.
Course Map
This course teaches frontend teams how to build regulated product workflows on top of the KYC API.
The course is now organized as topic pages. You can read it from start to finish, but you do not have to. Each page gives enough context to work on that topic directly, then links to the pages that naturally come before or after it.
What You Will Be Able To Build
After working through the course, you should be able to:
- Configure a browser application without leaking secrets.
- Build a typed TypeScript client for protected KYC API calls.
- Diagnose connectivity, readiness, and authentication problems.
- Render API errors as useful product states.
- Build quick screening as evidence, not a final decision.
- Create durable case workspaces.
- Save one case section at a time.
- Generate and read report snapshots.
- Display workflow progress without treating events as the compliance archive.
- Keep generated recommendations separate from human review decisions.
- Adapt the same integration pattern to banks, fintechs, insurers, lenders, marketplaces, and other regulated products.
Start Here
Use these pages first:
- Big Picture explains the product architecture and the learning path.
- Integration Boundary defines what the frontend should and should not know.
- Environment Configuration lists the public configuration values a frontend app needs.
- API Client gives the reusable TypeScript request wrapper used by every screen.
Choose A Workflow
If you are building a concrete product surface, start with one workflow:
| Goal | Start with |
|---|---|
| Show API status and user access | Read-Only Dashboard |
| Collect user or applicant details | Case Intake Form |
| Support analyst or reviewer work | Reviewer Workspace |
| Prepare a regulated frontend for release | Launch-Ready Frontend |
Each workflow links to smaller task pages instead of repeating the same implementation guidance.
Topic Types
The course uses predictable topic types:
| Topic type | Purpose |
|---|---|
| Big picture | Explains the full system and how the pages fit together. |
| Workflow | Shows an end-to-end product path and links to task pages. |
| Foundation | Establishes a reusable boundary, type, client, or state model. |
| Task | Builds one API-backed feature. |
| Quality | Verifies accessibility, audit readiness, tests, and launch safety. |
How To Use A Topic Page
Every implementation page follows the same rhythm:
- Use this when tells you whether the page matches your problem.
- What you will build defines the visible outcome.
- What must already be true lists the prerequisites.
- API contract names the endpoint or data shape.
- UI states turns API behavior into product behavior.
- Implementation steps gives the build sequence.
- Checkpoint gives a clear stopping point.
- Common mistakes prevents predictable integration bugs.
- Related pages points to adjacent work.
This keeps each page useful when reached from search, a teammate’s link, or an LLM coding agent.
Stable Implementation Order
When in doubt, build in this order:
configuration -> API client -> diagnostics -> errors -> screening -> cases -> reports -> review
Do not build every screen at once. Finish one visible layer, run its checkpoint, then move to the next layer.
Final Teaching Pattern
Use this sequence when coaching a frontend team:
- Prove the API is reachable.
- Prove authentication works.
- Prove structured errors are useful.
- Render evidence without making a decision.
- Persist the case.
- Save one section at a time.
- Generate the right report view.
- Show progress while work is active.
- Require an accountable human decision.
- Verify the customer-facing view hides restricted data.
That sequence turns an API integration into a reliable product workflow.
Big Picture
Use This When
Use this page when you need the overall map before choosing an implementation topic.
What You Will Build
You will build a frontend that turns the KYC API into regulated product workflows: diagnostics, screening, cases, section updates, reports, workflow progress, and human review.
What Must Already Be True
- You are building a browser or web application.
- The API owner can provide public frontend configuration.
- The target product has a sign-in flow or can add one.
Mental Model
Think of the KYC API as six frontend-facing capabilities.
| Capability | Frontend responsibility | API responsibility |
|---|---|---|
| Access | Sign in the user and send a short-lived bearer token. | Validate the token and authorize protected requests. |
| Diagnostics | Show whether the API is reachable and ready. | Expose health and readiness endpoints. |
| Screening evidence | Collect search input and render evidence clearly. | Return screening status, evidence status, limitations, and next steps. |
| Case workspace | Let operators create and update a review file. | Persist durable case records and section updates. |
| Report snapshots | Request the correct report view and display it safely. | Generate immutable report artifacts with snapshot metadata. |
| Human review | Require reviewer action and rationale. | Record accountable review decisions. |
The frontend orchestrates the experience. The API owns the regulated workflow contract.
Course Path
The stable learning path is:
- Draw the Integration Boundary.
- Configure the Environment.
- Build the API Client.
- Add Diagnostics.
- Convert failures into Error States.
- Build Quick Screening.
- Create Durable Cases.
- Save Case Sections.
- Generate Report Snapshots.
- Display Workflow Events.
- Submit Human Review Decisions.
- Run the Launch Checklist.
Checkpoint
You are ready to start implementation when you can explain:
- Which values are public browser configuration.
- Which credentials must never reach the browser.
- Which page owns diagnostics, errors, screening, cases, reports, and review.
- Which workflow you are building first.
Common Mistakes
- Building product screens before diagnostics.
- Treating quick screening as final approval.
- Mixing generated recommendations with human decisions.
- Showing compliance-only report data on customer-facing routes.
- Letting every screen invent its own API request logic.
Related Pages
Read-Only Dashboard
Use This When
Use this workflow when the first product goal is to show API status, user access, latest evidence, or report information without editing a case.
What You Will Build
You will build a dashboard that proves the API is reachable, the user can authenticate, and read-only KYC information can be displayed safely.
What Must Already Be True
- Environment Configuration is in place.
- API Client is implemented.
- The app has a route or panel for diagnostics and read-only data.
API Contract
Typical endpoints:
GET /healthz
GET /readyz
GET /api/v1/kyc/search
GET /api/v1/kyc-cases/{case_id}
GET /api/v1/kyc-cases/{case_id}/reports/latest?view={view}
GET /api/v1/workflow/events?after_id={after_id}&limit={limit}
Choose only the endpoints needed for the dashboard.
UI States
| Area | Required states |
|---|---|
| Diagnostics | Reachable, not reachable, ready, degraded. |
| Auth | Signed out, signed in, unauthorized. |
| Evidence | Empty, loading, success, partial evidence, error. |
| Report | No report, loading, snapshot available, restricted view. |
| Timeline | No events, polling, warning, error. |
Implementation Steps
- Add Diagnostics.
- Add Error States.
- Add Quick Screening if dashboard users need lightweight evidence lookup.
- Add Report Snapshots when the dashboard displays generated summaries.
- Add Workflow Events when active work is visible.
Checkpoint
- A user can tell whether the API, readiness, and auth are working.
- Read-only views do not expose restricted compliance fields to customer-facing audiences.
- Support details preserve API request metadata when failures occur.
Common Mistakes
- Starting with reports before diagnostics works.
- Rendering compliance report data in a general support dashboard.
- Polling workflow events after the dashboard is no longer visible.
- Treating read-only UI as permission enforcement.
Related Pages
Case Intake Form
Use This When
Use this workflow when the frontend collects applicant, customer, borrower, seller, or policyholder details and creates a durable case.
What You Will Build
You will build intake that validates input, optionally runs quick screening, creates a durable case, and routes the user to a case workspace.
What Must Already Be True
- The app has browser-safe auth.
- The shared API Client exists.
- Required public configuration is available.
API Contract
Typical endpoints:
GET /api/v1/kyc/search
POST /api/v1/kyc-cases
PATCH /api/v1/kyc-cases/{case_id}/sections/{section_name}
Use quick screening before case creation only when it helps the product flow.
UI States
| Area | Required states |
|---|---|
| Form | Empty, invalid, ready, submitting. |
| Screening | Not run, running, evidence available, partial evidence. |
| Case creation | Saving, created, duplicate external ID, validation error. |
| Navigation | Stay on form for fixable errors, route to workspace on success. |
Implementation Steps
- Add Error States.
- Add Quick Screening when intake needs a first evidence pass.
- Add Create Durable Cases.
- Add Case Sections if intake saves additional sections after the case exists.
- Run Accessible Product States for form labels, validation, keyboard behavior, and focus handling.
Checkpoint
- Missing or invalid input is caught before submit when possible.
- API validation errors map back to the form.
- Duplicate external case IDs show a recovery path.
- Successful creation moves the user to the case workspace.
Common Mistakes
- Saving a durable case before the user has entered required identity context.
- Treating a quick screening result as the final intake decision.
- Losing form state when the API returns a validation error.
- Requiring an external case ID when the API can generate one safely.
Related Pages
Reviewer Workspace
Use This When
Use this workflow when analysts or authorized reviewers need to inspect a case, save sections, read reports, track progress, and submit decisions.
What You Will Build
You will build the primary regulated review surface: case detail, section editing, evidence panels, reports, workflow timeline, and decision submission.
What Must Already Be True
- A durable case can be created or loaded.
- The user is authenticated and authorized for reviewer work.
- Customer-facing and reviewer-facing routes are separated.
API Contract
Typical endpoints:
GET /api/v1/kyc-cases/{case_id}
PATCH /api/v1/kyc-cases/{case_id}/sections/{section_name}
POST /api/v1/kyc-cases/{case_id}/reports/end-user-v1
GET /api/v1/kyc-cases/{case_id}/reports/latest?view={view}
GET /api/v1/workflow/events?after_id={after_id}&limit={limit}
POST /api/v1/kyc-cases/{case_id}/review-decisions
UI States
| Area | Required states |
|---|---|
| Case detail | Loading, found, missing, unauthorized. |
| Sections | Clean, dirty, saving, saved, validation error. |
| Evidence | Available, partial, unavailable, restricted. |
| Reports | No snapshot, generating, cache hit, cache miss, restricted. |
| Events | Polling, idle, warning, error. |
| Decision | Not ready, rationale required, submitting, submitted. |
Implementation Steps
- Load the case and render server-owned fields as read-only.
- Add Case Sections.
- Add evidence panels from Quick Screening or saved screening sections.
- Add Report Snapshots.
- Add Workflow Events.
- Add Human Review Decisions.
- Run Audit-Ready UI before launch.
Checkpoint
- Reviewers can understand evidence, reports, workflow progress, and required decisions without mixing them together.
- Recommendations and human decisions are visually separate.
- Restricted sections do not appear in customer-facing routes.
Common Mistakes
- Putting every case field into one large form.
- Hiding report view type or snapshot metadata from reviewers.
- Letting the decision button submit without rationale.
- Showing generated recommendations as if they were decisions.
Related Pages
Launch-Ready Frontend
Use This When
Use this workflow when a prototype is moving toward production use in a regulated product.
What You Will Build
You will turn a working integration into a launch-ready frontend by checking configuration, security boundaries, accessible states, audit readiness, tests, and release assumptions.
What Must Already Be True
- The main product workflow is implemented.
- The app can call the API in at least one non-production environment.
- Auth, CORS or origin allowlist, and protected endpoint access can be verified.
API Contract
The launch gate should cover every endpoint your product calls, especially:
GET /healthz
GET /readyz
GET /api/v1/kyc/search
POST /api/v1/kyc-cases
PATCH /api/v1/kyc-cases/{case_id}/sections/{section_name}
POST /api/v1/kyc-cases/{case_id}/reports/end-user-v1
GET /api/v1/kyc-cases/{case_id}/reports/latest?view={view}
POST /api/v1/kyc-cases/{case_id}/review-decisions
UI States
Launch-ready means every critical flow has:
- Empty state.
- Loading state.
- Success state.
- Validation error state.
- Auth or permission error state.
- Conflict state where relevant.
- Retry or support handoff state when relevant.
Implementation Steps
- Run Accessible Product States.
- Run Audit-Ready UI.
- Run Testing Checklist.
- Run Launch Checklist.
- Verify production configuration outside the source tree.
- Confirm support handoff includes request metadata without exposing secrets.
Checkpoint
- The app has a verified path for diagnostics, auth, validation errors, conflicts, screening, case creation, section save, report generation, workflow progress, and review decision submission.
Common Mistakes
- Calling a prototype launch-ready because the happy path works once.
- Skipping customer-safe report verification.
- Leaving private values in public environment examples.
- Not testing duplicate external IDs or expired-token behavior.
Related Pages
Integration Boundary
Use This When
Use this page before writing API calls, auth wiring, or UI screens.
What You Will Build
You will define the browser-safe boundary for a frontend integration with the KYC API.
What Must Already Be True
- You know which frontend application will call the API.
- You can get public configuration from the API owner.
- You have a user sign-in strategy or a plan to add one.
API Contract
The frontend can rely on public API endpoints and response contracts. It should not depend on internal hosting, storage, scoring, routing, or operator tooling.
The browser may contain:
- Public API base URL.
- Public auth issuer URL.
- Public frontend auth client ID.
- Redirect URI.
- Post-logout redirect URI.
- Required API audience or scope when provided.
The browser must never contain:
- Service-account keys.
- Private keys.
- Backend secrets.
- Database URLs.
- Token-introspection credentials.
- Long-lived bearer credentials.
- Provider credentials.
UI States
The boundary should show up in the product:
| State | Product behavior |
|---|---|
| Missing public config | Stop startup or show setup diagnostics. |
| Missing user token | Show sign-in state. |
| Unauthorized request | Recover auth or send the user to sign in. |
| Support handoff | Preserve API request_id and trace_id when present. |
Implementation Steps
- List every runtime value the frontend needs.
- Classify each value as public browser config or server-side secret.
- Add startup validation for required public values.
- Route all protected calls through one API client.
- Preserve structured API error metadata for support.
Checkpoint
- Environment files do not contain private credentials.
- Protected calls use the current user’s bearer token.
- UI copy does not promise that screening evidence equals final approval.
Common Mistakes
- Reusing a machine-to-machine credential in browser code.
- Logging access tokens or regulated payloads.
- Hardcoding deployment-specific values in reusable source.
- Exposing operator-only endpoints to ordinary end users.
Related Pages
Environment Configuration
Use This When
Use this page when wiring a frontend app to a real API environment.
What You Will Build
You will define environment-specific public configuration for the browser app and keep private values out of source code.
What Must Already Be True
- The API owner has assigned an API base URL.
- The auth owner has configured a public browser client.
- The frontend origin is allowed by the API owner.
API Contract
Before production wiring, get these values:
KYC API base URL
Auth issuer URL
Public frontend client ID
Redirect URI
Post-logout redirect URI
Required API audience or scope
Allowed frontend origin
Support contact or escalation path
For a Vite application, public variables usually look like:
VITE_KYC_API_BASE_URL=https://api.example.com
VITE_AUTH_ISSUER=https://identity.example.com
VITE_AUTH_CLIENT_ID=public-browser-client-id
VITE_AUTH_REDIRECT_URI=http://localhost:5173/auth/callback
VITE_AUTH_POST_LOGOUT_REDIRECT_URI=http://localhost:5173/
VITE_AUTH_AUDIENCE_SCOPE=api-audience-scope
Use the target application’s naming convention when it differs from Vite.
UI States
Configuration should support these states:
| State | Product behavior |
|---|---|
| Config valid | Enable diagnostics and sign-in. |
| API base URL missing | Show setup error before protected screens load. |
| Auth issuer missing | Disable sign-in and show setup guidance. |
| Origin not allowed | Diagnostics should point to CORS or origin allowlist. |
Implementation Steps
- Add a small config module at the frontend app boundary.
- Read only public environment variables in browser code.
- Validate required values at startup.
- Fail clearly when a required value is missing.
- Link config errors to the diagnostics screen.
Checkpoint
- Local development can load public config.
- Production config can be supplied without changing source code.
- No private key, service credential, database URL, or long-lived token appears in the frontend bundle.
Common Mistakes
- Treating public client IDs as secrets.
- Treating service credentials as public config.
- Committing
.envfiles. - Letting a missing config value produce a generic blank screen.
Related Pages
API Client
Use This When
Use this page when adding the first real API calls to a frontend application.
What You Will Build
You will build one small TypeScript API client that attaches user tokens, parses JSON, and converts non-2xx responses into structured errors.
What Must Already Be True
- Public API configuration is available.
- The application can provide the current user’s access token or
null. - The frontend has a place for shared API modules.
API Contract
Protected API calls send:
Authorization: Bearer <access_token>
The token must come from the current user’s browser sign-in flow, normally authorization code with PKCE or an equivalent repository-provided pattern.
Implementation Steps
Start with one client that is independent from UI components:
export type KycApiClientOptions = {
baseUrl: string;
getAccessToken: () => Promise<string | null>;
};
export type KycApiErrorBody = {
code: string;
message: string;
developer_message?: string;
category?: string;
http_status?: number;
request_id?: string;
trace_id?: string;
retryable?: boolean;
docs_url?: string;
details?: Record<string, unknown>;
};
export class KycApiError extends Error {
readonly developerMessage?: string;
readonly category?: string;
readonly requestId?: string;
readonly traceId?: string;
readonly retryable: boolean;
readonly details?: Record<string, unknown>;
constructor(
message: string,
readonly status: number,
readonly code?: string,
readonly responseBody?: unknown
) {
super(message);
const body = (responseBody as { error?: KycApiErrorBody } | null)?.error;
this.developerMessage = body?.developer_message;
this.category = body?.category;
this.requestId = body?.request_id;
this.traceId = body?.trace_id;
this.retryable = body?.retryable ?? false;
this.details = body?.details;
}
get field(): string | undefined {
return typeof this.details?.field === "string" ? this.details.field : undefined;
}
}
Wrap fetch once:
export class KycApiClient {
constructor(private readonly options: KycApiClientOptions) {}
get<T>(path: string): Promise<T> {
return this.request<T>("GET", path);
}
post<T>(path: string, body: unknown): Promise<T> {
return this.request<T>("POST", path, body);
}
patch<T>(path: string, body: unknown): Promise<T> {
return this.request<T>("PATCH", path, body);
}
private async request<T>(
method: "GET" | "POST" | "PATCH",
path: string,
body?: unknown
): Promise<T> {
const token = await this.options.getAccessToken();
const response = await fetch(new URL(path, this.options.baseUrl), {
method,
headers: {
Accept: "application/json",
...(body ? { "Content-Type": "application/json" } : {}),
...(token ? { Authorization: `Bearer ${token}` } : {})
},
body: body ? JSON.stringify(body) : undefined
});
const text = await response.text();
const parsed = text ? JSON.parse(text) : null;
if (!response.ok) {
throw new KycApiError(
parsed?.error?.message ?? `KYC API returned HTTP ${response.status}`,
response.status,
parsed?.error?.code,
parsed
);
}
return parsed as T;
}
}
Create the instance at the app boundary:
export const kycApi = new KycApiClient({
baseUrl: import.meta.env.VITE_KYC_API_BASE_URL,
getAccessToken
});
UI States
The API client should make these states easy to render:
| State | Source |
|---|---|
| Loading | The request promise is pending. |
| Success | The typed response is returned. |
| Validation error | KycApiError.status === 400. |
| Auth error | KycApiError.status === 401. |
| Conflict | KycApiError.status === 409. |
| Retry later | KycApiError.retryable === true. |
Checkpoint
- All API calls use the same client.
- Protected requests attach
Authorization: Bearer <access_token>. - Non-2xx responses throw
KycApiError. request_idis available for support handoff.
Common Mistakes
- Creating one
fetchwrapper per screen. - Dropping
request_idfrom errors. - Assuming every response body is valid JSON without reading the response text.
- Retrying compliance-changing mutations blindly.
Related Pages
Diagnostics
Use This When
Use this page before building product screens or when an integration fails in a new environment.
What You Will Build
You will build a diagnostics screen that separates API reachability, readiness, and authentication problems.
What Must Already Be True
- Public API base URL is configured.
- The shared API Client exists.
- The application can tell whether a user is signed in.
API Contract
Public operational endpoints:
GET /healthz
GET /readyz
Suggested response types:
export type HealthResponse = {
status: string;
release?: string;
runtime?: {
git_sha?: string;
image_ref?: string;
fly_app_name?: string;
fly_process_group?: string;
fly_region?: string;
};
};
export type ReadinessResponse = {
status: string;
release?: string;
runtime?: HealthResponse["runtime"];
checks?: Array<{
name: string;
ok: boolean;
detail?: string;
}>;
};
Load public diagnostics:
export async function loadApiDiagnostics(client: KycApiClient) {
const [health, readiness] = await Promise.all([
client.get<HealthResponse>("/healthz"),
client.get<ReadinessResponse>("/readyz")
]);
return { health, readiness };
}
After sign-in, verify one protected endpoint that matches the product you are building.
UI States
| State | Meaning | User action |
|---|---|---|
| Reachable | Browser can call public API endpoints. | Continue setup. |
| Not reachable | Network, base URL, CORS, or DNS may be wrong. | Check API base URL and frontend origin. |
| Ready | API reports it can handle work. | Continue product flow. |
| Degraded | API is reachable but not fully ready. | Show diagnostics and retry later. |
| Authenticated | User token is present and accepted. | Enable protected flows. |
| Unauthorized | Token is missing, expired, or invalid. | Sign in again. |
Developer diagnostics should show the API release, deployment/runtime
metadata, and any failed readiness check names. Do not show /metrics in
customer-facing UI; it is an operator/debug endpoint.
Implementation Steps
- Add a diagnostics route or admin-only panel.
- Call
/healthzand/readyzwithout requiring sign-in. - Show configuration, reachability, readiness, and auth as separate rows.
- After sign-in, call one protected endpoint and show whether the token works.
- Include
request_idwhen a protected diagnostic request fails.
Checkpoint
- A developer can diagnose base URL, readiness, and auth problems without opening browser devtools.
- A developer can compare the frontend environment against the backend release currently serving the API.
- The diagnostics page does not expose private credentials or regulated data.
Common Mistakes
- Hiding diagnostics behind the same auth problem being diagnosed.
- Calling only protected endpoints and missing CORS or readiness failures.
- Showing raw tokens in debug output.
- Treating degraded readiness as a user input error.
Related Pages
Error States
Use This When
Use this page when turning API failures into clear UI behavior.
What You Will Build
You will map structured API errors to validation messages, auth recovery, missing-resource screens, conflict resolution, retry states, and support handoff.
What Must Already Be True
- The shared API Client throws
KycApiError. - The UI has a place to render field, form, page, and support messages.
API Contract
Preserve these fields when the API returns them:
status
code
message
developer_message
category
request_id
trace_id
retryable
details
Useful guards:
export function isValidationError(error: unknown): error is KycApiError {
return error instanceof KycApiError && error.status === 400;
}
export function isUnauthorized(error: unknown): error is KycApiError {
return error instanceof KycApiError && error.status === 401;
}
export function isConflict(error: unknown): error is KycApiError {
return error instanceof KycApiError && error.status === 409;
}
export function isRetryableServiceError(error: unknown): error is KycApiError {
return error instanceof KycApiError && error.retryable;
}
UI States
| Status | UI behavior |
|---|---|
| 400 | Show field or form validation. Use details.field when present. |
| 401 | Refresh login or redirect to sign in. |
| 404 | Show missing resource state and route back to a safe page. |
| 409 | Offer to load the existing case or create a new external identifier. |
| 429 | Show overloaded/retry-later state and use Retry-After or exponential backoff. |
| 503 | Show degraded service, retry later, and include request_id in support details. |
Implementation Steps
- Create one error-to-UI mapping module.
- Render field errors near the relevant form inputs.
- Render auth failures as sign-in recovery, not data-entry mistakes.
- Render conflicts as recoverable choices.
- Render retryable failures with retry and support handoff.
Checkpoint
- Field errors appear near the relevant input.
- Authentication errors do not look like validation errors.
- Conflict errors give the operator a recoverable path.
- Support details include
request_idwhen the API provides it. - Retryable overload errors are handled without repeatedly hammering the API.
Common Mistakes
- Collapsing all failures into “Something went wrong.”
- Hiding developer context that support needs.
- Showing developer-only messages to customers.
- Retrying non-idempotent actions without user intent.
Related Pages
Data Shapes And Vocabulary
Use This When
Use this page when naming types, UI labels, route names, or documentation in a frontend implementation.
What You Will Build
You will keep product language consistent across code, screens, support handoff, and tests.
What Must Already Be True
- You have read the Big Picture.
- You know which workflow the frontend will support first.
Vocabulary
| Term | Meaning |
|---|---|
| API client | The frontend module that wraps fetch, attaches tokens, and parses errors. |
| Diagnostics | Health, readiness, and authenticated access checks. |
| Quick screening | A lightweight evidence search. It is not a final approval. |
| Case | A durable review file for one customer, seller, borrower, policyholder, or subject. |
| Section | One named part of a case file, saved independently. |
| Report snapshot | A generated report artifact with ID, hash, view, timestamp, and payload. |
| Workflow event | A progress event for active work. It is not the permanent compliance archive. |
| Recommendation | Generated or assisted guidance shown to a reviewer. |
| Decision | The accountable human action submitted by an authorized reviewer. |
The API uses technical parameter names such as include_web_search. Your UI can
label the same control “evidence search” if that is clearer for users.
UI States
Vocabulary should make state obvious:
| State | Preferred language |
|---|---|
| Evidence only | “Screening evidence” or “evidence search result”. |
| Human action required | “Reviewer decision required”. |
| Customer-safe report | “Customer summary” or product-specific equivalent. |
| Restricted data | “Internal review only” or role-specific label. |
Implementation Steps
- Create shared TypeScript types for API concepts.
- Use product labels in the UI while preserving API field names in client code.
- Keep recommendations, decisions, reports, and events as separate types.
- Add test fixtures using the same vocabulary as the UI.
Checkpoint
- A teammate can read a screen, test, or type name and know whether it is evidence, a recommendation, a decision, an event, or a report snapshot.
Common Mistakes
- Calling a quick screening result “approved”.
- Treating workflow events as the audit archive.
- Mixing customer-safe and compliance report views in one component.
- Using different names for the same concept in code and UI.
Related Pages
Quick Screening
Use This When
Use this page when an operator needs a lightweight evidence check before opening or updating a durable case.
What You Will Build
You will build a search form and results view that presents screening evidence, limitations, and next steps without presenting the result as final approval.
What Must Already Be True
- API Client is implemented.
- Error States are mapped.
- The user can authenticate for protected API calls.
API Contract
Endpoint:
GET /api/v1/kyc/search
Request query:
name={name}
date_of_birth={date_of_birth}
nationality={nationality}
include_web_search={true_or_false}
limit={limit}
Only name is required.
TypeScript shape:
export type KycSearchParams = {
name: string;
dateOfBirth?: string;
nationality?: string;
includeEvidenceSearch?: boolean;
limit?: number;
};
export async function searchKyc(client: KycApiClient, params: KycSearchParams) {
const query = new URLSearchParams({
name: params.name,
include_web_search: String(params.includeEvidenceSearch ?? true),
limit: String(params.limit ?? 5)
});
if (params.dateOfBirth) {
query.set("date_of_birth", params.dateOfBirth);
}
if (params.nationality) {
query.set("nationality", params.nationality);
}
return client.get<KycSearchResponse>(`/api/v1/kyc/search?${query}`);
}
Render these response areas:
- Subject and generated timestamp.
- Overall status and risk level.
- Local sanctions screening status and source versions.
- Evidence-search status, result counts, and query-level failures.
- Recommended next steps.
- Limitations.
UI States
| State | Product behavior |
|---|---|
| Empty | Show a short form with required name. |
| Loading | Disable submit and show that screening is running. |
| Success | Render evidence, limitations, and next steps. |
| Partial evidence | Show degraded query/source information clearly. |
| Validation error | Put the message near the relevant input. |
| Auth error | Ask the user to sign in again. |
Implementation Steps
- Build a small form with name, optional date of birth, optional nationality, evidence-search toggle, and result limit.
- Validate name before calling the API.
- Call
searchKycthrough the shared client. - Render screening status and evidence-search status separately.
- Put limitations close to the summary.
- Offer a next action such as creating or opening a durable case.
Checkpoint
- A user can understand what was checked, what was degraded, and what should happen next.
- No quick-screening result is labeled as final approval.
Common Mistakes
- Converting risk level directly into an approval button.
- Hiding partial evidence failures.
- Dropping limitations below the fold where reviewers miss them.
- Logging raw search payloads to analytics.
Related Pages
Create Durable Cases
Use This When
Use this page when a workflow needs persistence, reviewer activity, report snapshots, future refreshes, or customer support handoff.
What You Will Build
You will build case creation that routes the user into a durable case workspace.
What Must Already Be True
- API Client is implemented.
- Form validation and Error States are ready.
- The product has a route for a case workspace or case detail page.
API Contract
Endpoint:
POST /api/v1/kyc-cases
Minimal frontend input shape:
export type KycCaseCreateInput = {
kyc_case_id?: string | null;
user_internal_id: string;
agency_name: string;
regulated_provider_name: string;
programme_name: string;
country_of_onboarding: string;
relationship_type:
| "NEW_ONBOARDING"
| "KYC_REFRESH"
| "LIMIT_INCREASE"
| "REMEDIATION"
| "REACTIVATION";
user_type:
| "INDIVIDUAL"
| "SOLE_TRADER"
| "LEGAL_REPRESENTATIVE"
| "BENEFICIAL_OWNER";
current_status:
| "DRAFT"
| "DOCUMENTS_SUBMITTED"
| "EXTRACTION_IN_PROGRESS"
| "EXTRACTION_FAILED"
| "PENDING"
| "PENDING_REVIEW"
| "WAITING_FOR_CUSTOMER"
| "ESCALATED"
| "SUSPENDED";
case_priority: "LOW" | "NORMAL" | "HIGH" | "URGENT";
assigned_team: string;
assigned_analyst_name?: string | null;
assigned_analyst_email?: string | null;
legal_first_name: string;
legal_last_name: string;
};
export async function createKycCase(
client: KycApiClient,
input: KycCaseCreateInput
) {
return client.post<{ principal: string; case: KycCaseRecord }>(
"/api/v1/kyc-cases",
input
);
}
UI States
| State | Product behavior |
|---|---|
| Draft | Let the user enter required case fields. |
| Saving | Disable duplicate submit and show progress. |
| Created | Route to the case workspace. |
| Conflict | Offer to load the existing case or use a new external ID. |
| Validation error | Show field-level guidance. |
| Server-owned fields | Display as read-only after creation. |
Implementation Steps
- Let the API generate
kyc_case_idunless your product owns a stable external case ID. - Keep final statuses out of the creation form.
- Validate required fields before submit.
- Submit through
createKycCase. - On success, navigate to the case workspace.
- On duplicate external ID, show a recoverable conflict state.
Checkpoint
- Creating a case routes the user into a case workspace.
- Server-owned fields are displayed but not edited.
- A duplicate external ID shows a conflict path, not a crash.
Common Mistakes
- Allowing users to create final states directly.
- Treating server-owned fields as editable inputs.
- Creating a new case for every quick screening result.
- Losing the API
request_idon conflict or validation failures.
Related Pages
Case Sections
Use This When
Use this page when a case workspace needs to save one part of a case at a time.
What You Will Build
You will build section updates for smaller forms, safer autosave, and clearer review screens.
What Must Already Be True
- A durable case exists.
- The UI knows the current
case_id. - The product can decide which sections are visible to each role.
API Contract
Endpoint:
PATCH /api/v1/kyc-cases/{case_id}/sections/{section_name}
Body:
{
"payload": {}
}
Common section names:
export type KycSectionName =
| "service_context"
| "end_user_identity"
| "contact_verification"
| "identity_document_verification"
| "address_verification"
| "screening"
| "risk_assessment"
| "decision"
| "user_facing_summary"
| "restricted_compliance_notes";
export async function patchKycSection(
client: KycApiClient,
caseId: string,
sectionName: KycSectionName,
payload: Record<string, unknown>
) {
return client.patch<{ principal: string; section: unknown }>(
`/api/v1/kyc-cases/${encodeURIComponent(caseId)}/sections/${sectionName}`,
{ payload }
);
}
UI States
| Section | Typical screen |
|---|---|
end_user_identity | Identity details and subject profile. |
contact_verification | Email, phone, and contact checks. |
identity_document_verification | Document review status. |
address_verification | Residence and proof-of-address status. |
screening | Screening evidence and match review. |
risk_assessment | Risk rationale and review notes. |
user_facing_summary | Customer-safe explanation. |
restricted_compliance_notes | Internal-only compliance notes. |
Implementation Steps
- Split the case workspace into section components.
- Give each section its own draft, saving, saved, and error states.
- Save one section at a time.
- Refresh the case or section data after a successful save.
- Hide restricted sections from customer-facing routes.
- Keep backend authorization as the enforcement point.
Checkpoint
- A section save updates only that part of the case.
- Restricted sections are hidden from customer-facing routes.
- Frontend role gating improves usability, while backend authorization remains the enforcement point.
Common Mistakes
- Submitting the entire case for every small edit.
- Assuming hidden frontend fields are a security control.
- Saving restricted notes from customer routes.
- Losing unsaved form state after a section error.
Related Pages
Report Snapshots
Use This When
Use this page when the frontend needs generated reports for customers, partners, providers, or internal reviewers.
What You Will Build
You will generate and read report snapshots with the correct view for the audience.
What Must Already Be True
- A durable case exists.
- The user is authorized for the requested report view.
- Customer-facing and internal routes are separated.
API Contract
Generate:
POST /api/v1/kyc-cases/{case_id}/reports/end-user-v1
Read latest:
GET /api/v1/kyc-cases/{case_id}/reports/latest?view={view}
Allowed views:
user_safe
provider_export
compliance
TypeScript helpers:
export type ReportView = "compliance" | "provider_export" | "user_safe";
export async function generateEndUserReport(
client: KycApiClient,
caseId: string,
view: ReportView
) {
return client.post<{
principal: string;
cache_status: "HIT" | "MISS";
report_snapshot_id: string;
generated_at: string;
input_fingerprint: string;
snapshot_hash: string;
view_type: "COMPLIANCE" | "PROVIDER_EXPORT" | "USER_SAFE";
report: unknown;
}>(`/api/v1/kyc-cases/${encodeURIComponent(caseId)}/reports/end-user-v1`, {
view,
generated_by: "frontend-webapp"
});
}
export async function loadLatestReport(
client: KycApiClient,
caseId: string,
view: ReportView
) {
return client.get(
`/api/v1/kyc-cases/${encodeURIComponent(caseId)}/reports/latest?view=${encodeURIComponent(view)}`
);
}
UI States
| View | Use it for |
|---|---|
user_safe | Customer portals and support experiences. |
provider_export | Partner or regulated-provider handoff. |
compliance | Authorized internal review workspaces. |
Show snapshot metadata in operator-facing screens:
cache_statusreport_snapshot_idsnapshot_hashgenerated_atview_type
Implementation Steps
- Choose report view based on route and role.
- Generate a report snapshot only when the user requests or workflow requires it.
- Display customer-safe reports in customer-facing routes.
- Display snapshot metadata in internal operator routes.
- Do not render restricted notes in customer-facing routes.
Checkpoint
- Customer routes use
user_safe. - Internal review routes can show snapshot metadata.
- Restricted notes, internal scoring details, and control logic do not appear in customer-facing experiences.
Common Mistakes
- Using one report view everywhere.
- Rendering compliance payloads in customer support routes.
- Hiding snapshot metadata that operators need for support.
- Regenerating reports on every page load.
Related Pages
Workflow Events
Use This When
Use this page when the frontend needs to show progress while work is active.
What You Will Build
You will poll workflow events, merge them without duplicates, and display warnings and errors clearly.
What Must Already Be True
- API Client is implemented.
- The UI has a timeline, activity panel, or progress region.
- The product knows when active work is visible.
API Contract
Endpoint:
GET /api/v1/workflow/events?after_id={after_id}&limit={limit}
Response shape:
export type WorkflowEvent = {
id: number;
timestamp: string;
level: "info" | "warning" | "error";
stage: string;
message: string;
metadata: Record<string, unknown>;
};
export async function loadWorkflowEvents(client: KycApiClient, afterId: number) {
return client.get<{
principal: string;
events: WorkflowEvent[];
next_after_id: number;
}>(`/api/v1/workflow/events?after_id=${afterId}&limit=100`);
}
UI States
| State | Product behavior |
|---|---|
| No events | Show a calm empty timeline. |
| Polling | Show progress without blocking unrelated work. |
| Warning event | Highlight and explain the warning. |
| Error event | Show failure state and support details when available. |
| Tab hidden | Slow or pause polling. |
Implementation Steps
- Start with
after_id=0. - Store
next_after_idafter each response. - Merge events by
event.id. - Poll only while active work is visible.
- Slow or stop polling when the browser tab is hidden.
- Show warning and error events as first-class UI states.
Checkpoint
- Event polling does not create duplicates.
- Warning and error events are visible.
- The UI treats workflow events as progress, not permanent compliance history.
Common Mistakes
- Polling forever after the user leaves the page.
- Appending duplicate events.
- Treating workflow events as the audit archive.
- Hiding warning and error events in a collapsed debug panel.
Related Pages
Human Review Decisions
Use This When
Use this page when an authorized reviewer must make an accountable decision.
What You Will Build
You will build a review panel that separates evidence, generated recommendations, and the human decision.
What Must Already Be True
- A durable case exists.
- Evidence and reports are visible to the reviewer.
- The reviewer is authorized to submit decisions.
API Contract
Endpoint:
POST /api/v1/kyc-cases/{case_id}/review-decisions
Allowed decision outcomes:
approved
rejected
needs_more_information
escalated
TypeScript helper:
export type ReviewDecisionOutcome =
| "approved"
| "rejected"
| "needs_more_information"
| "escalated";
export async function submitReviewDecision(
client: KycApiClient,
caseId: string,
body: {
proposal_id?: string | null;
decision_outcome: ReviewDecisionOutcome;
rationale: string;
decision_payload?: Record<string, unknown>;
corrections?: Array<Record<string, unknown>>;
}
) {
return client.post<{ principal: string; review_decision: unknown }>(
`/api/v1/kyc-cases/${encodeURIComponent(caseId)}/review-decisions`,
body
);
}
UI States
A good review screen has three zones:
| Zone | Purpose |
|---|---|
| Evidence | What the API returned and what the reviewer should inspect. |
| Recommendation | Suggested outcome, rationale, and limitations. |
| Decision | The human action, rationale, and final submission control. |
Decision form states:
- No decision selected.
- Decision selected but rationale missing.
- Ready to submit.
- Submitting.
- Submitted.
- Authorization or validation error.
Implementation Steps
- Show evidence first.
- Show recommendations in a visually separate area.
- Require explicit reviewer outcome selection.
- Require rationale before submit.
- Disable final submit while save or report operations are pending.
- Treat
needs_more_informationas workflow state, not a technical error. - After submitting
needs_more_information, update the case UI from the API response and expectresulting_status: "WAITING_FOR_CUSTOMER".
Checkpoint
- Recommendation and decision are visually separate.
- The final decision requires a reviewer action.
- The decision form requires rationale.
needs_more_informationis treated as workflow state, not a technical error.- Frontend state watches the returned case status instead of polling for a separate report-generation job state.
Common Mistakes
- Combining recommendation and decision into one button.
- Letting an empty rationale through.
- Enabling final submit while other case saves are pending.
- Presenting generated text as the accountable decision.
Related Pages
Accessible Product States
Use This When
Use this page when building or reviewing any screen that calls the KYC API.
What You Will Build
You will make every visible API-backed state understandable, keyboard reachable, and screen-reader friendly.
What Must Already Be True
- The screen has a clear user goal.
- The API client and error mapping exist.
- The product owner knows which roles can use the screen.
UI State Contract
Every critical surface should handle:
| State | Requirement |
|---|---|
| Empty | Explain what the user can do next. |
| Loading | Show progress without moving layout unexpectedly. |
| Success | Show the result and the next safe action. |
| Validation error | Put the message near the input. |
| Auth error | Show sign-in recovery. |
| Permission error | Explain that access is restricted. |
| Conflict | Offer a recoverable choice. |
| Retryable service failure | Show retry and support handoff. |
Implementation Steps
- Use semantic HTML for forms, tables, lists, and status regions.
- Label every input.
- Keep keyboard focus visible.
- Move focus intentionally after route changes, modal opens, and form errors.
- Do not use color alone to communicate risk, status, or severity.
- Keep long operations from blocking unrelated navigation.
- Preserve API
request_idin support details when available.
Checkpoint
- A user can complete the screen with a keyboard.
- Errors are readable without relying on color.
- Loading, empty, success, and error states are all visible in tests or manual review.
Common Mistakes
- Building only the success state.
- Showing validation errors in a global toast with no field association.
- Moving focus unpredictably after save.
- Hiding retryable failures behind generic copy.
Related Pages
Audit-Ready UI
Use This When
Use this page when the frontend displays regulated evidence, reports, restricted sections, recommendations, or decisions.
What You Will Build
You will make the UI clear about what is evidence, what is generated guidance, what is a human decision, and what is safe for each audience.
What Must Already Be True
- The product has identified customer-facing and reviewer-facing routes.
- Report view types are understood.
- Role-based visibility has been designed for the frontend.
UI Contract
| Concept | UI rule |
|---|---|
| Evidence | Show source, status, limitations, and next steps. |
| Recommendation | Present as guidance, not final action. |
| Human decision | Require explicit reviewer choice and rationale. |
| Report snapshot | Preserve view type, generated timestamp, snapshot ID, and hash where appropriate. |
| Customer-safe view | Hide restricted notes, internal scoring, and compliance-only details. |
| Restricted section | Hide from customer routes and rely on backend authorization for enforcement. |
Implementation Steps
- Use separate components for evidence, recommendation, decision, and report snapshot metadata.
- Display report view type in reviewer-facing report screens.
- Keep customer-safe report rendering separate from compliance report rendering.
- Show limitations close to screening summaries.
- Require rationale before decision submission.
- Exclude personal and regulated data from analytics and client logs.
Checkpoint
- A reviewer can tell the difference between evidence, recommendation, and decision.
- Customer routes render only customer-safe report information.
- Restricted notes do not appear in customer-facing components.
Common Mistakes
- Reusing one report component for every audience.
- Putting the final decision button inside the recommendation component.
- Hiding limitations in a secondary tab.
- Logging raw regulated payloads during debugging.
Related Pages
Testing Checklist
Use This When
Use this page when adding automated tests or preparing a release branch.
What You Will Build
You will verify the integration with tests that cover the product states a regulated frontend depends on.
What Must Already Be True
- The target repository has a test runner or component testing strategy.
- API calls are routed through the shared client.
- External API calls can be mocked or tested against a controlled environment.
Test Contract
Run the target repository’s actual commands. Prefer:
pnpm typecheck
pnpm lint
pnpm test
pnpm build
If the repository uses npm, yarn, bun, or another tool, use that instead.
Minimum Verification Scenarios
- Public health endpoint renders reachable state.
- Public readiness endpoint renders ready or degraded state.
- Protected request without token redirects or shows sign-in state.
- Quick screening form validates missing or short name.
- Quick screening success renders evidence and limitations.
- API validation error maps to form error.
- API 401 maps to auth recovery.
- API 409 maps to conflict UI.
- Case creation success routes to case workspace.
- Section save updates UI without losing unsaved form state.
- Report generation shows
HITorMISScache status. - Workflow polling merges events without duplicates.
- Review decision requires rationale.
- Customer route does not render compliance-only fields.
Implementation Steps
- Add unit tests for API client error parsing.
- Add component tests for form validation and error rendering.
- Add route or integration tests for diagnostics and auth recovery.
- Add workflow tests for case creation, section save, report generation, and review decision.
- Add customer-route tests that assert restricted fields are absent.
Checkpoint
- The happy path and the main failure paths are covered.
- Tests assert visible product behavior, not only function calls.
- Test fixtures do not contain real customer data or secrets.
Common Mistakes
- Mocking the API client so heavily that error parsing is never tested.
- Testing only the success path.
- Forgetting customer-safe report assertions.
- Leaving real regulated payloads in snapshots or fixtures.
Related Pages
Launch Checklist
Use This When
Use this page before moving from prototype to production or before asking a regulated team to rely on the frontend.
What You Will Build
You will complete the final release check for configuration, auth, security boundaries, product states, tests, and support handoff.
What Must Already Be True
- The main workflow has been implemented.
- Tests have been added for critical states.
- A non-production environment can call the API.
Launch Gate
Confirm:
- The API base URL is environment-specific.
- The frontend origin is allowed by the API owner.
- Browser authentication uses a public client flow.
- No private service credential is shipped to the browser.
- Protected requests send
Authorization: Bearer <access_token>. - Errors display useful user states and preserve
request_idfor support. - Developer diagnostics show backend
releaseand failed readiness checks. - Request and response types are generated from, or manually reviewed against, the checked OpenAPI contract.
- Quick screening is not presented as final approval.
- Customer screens use customer-safe report views.
- Internal-only sections are hidden from customer-facing routes.
- Human review actions require explicit rationale.
- Human follow-up uses
needs_more_information; the case workspace should then watchWAITING_FOR_CUSTOMERas the resulting case status. - Personal and regulated data are excluded from analytics and client logs.
- The application has tests for diagnostics, auth failures, validation errors, conflict errors, quick screening, case creation, report generation, workflow polling, and review decision submission.
Implementation Steps
- Run local type, lint, test, and build commands.
- Verify auth and protected endpoint access in the target environment.
- Verify report view permissions.
- Review browser bundle and environment files for private values.
- Confirm support handoff includes API request metadata.
- Document any environment-specific values outside the source tree.
Checkpoint
- A reviewer can trace each critical product state to a screen and a test.
- No secret or private credential is present in public source.
- Any unverified production dependency is documented before launch.
Common Mistakes
- Treating a passing build as a complete launch gate.
- Skipping expired-token and duplicate-case tests.
- Relying on frontend visibility as the only protection for restricted fields.
- Claiming production readiness before CORS, auth claims, and protected endpoint access have been verified.
Related Pages
LLM Coder Agent Contract
The repository includes a root LLM.txt file for coding agents.
It is a plain-text implementation contract that describes:
- Mission and operating mode.
- Security rules.
- Required configuration inputs.
- API endpoint contracts.
- TypeScript client shape.
- Error handling.
- Feature plan.
- Testing and verification.
- Forbidden shortcuts.
- Done definition.
Use it when asking an autonomous coding agent to implement a frontend application against the KYC API.
Course Pages For Agents
Use these pages to orient an implementation:
- Course Map for the stable build order.
- Big Picture for the product architecture.
- Integration Boundary for browser-safe security rules.
- API Client for the shared request wrapper.
- Error States for UI failure handling.
- Testing Checklist for verification scenarios.
- Launch Checklist for final release gates.