Assetera Docs
Integrate

KYC integration (MetaKYC SDK)

Embed Assetera's KYC flow with the @asseteragmbh/metakyc React SDK. Create a session token on your server, then render the workflow in your app.

Assetera's identity verification runs through the MetaKYC SDK, published as @asseteragmbh/metakyc. You embed it in two moves: create a short-lived session token on your server, then render the KYC workflow in the browser using that token.

Ignore examples/nextjs in the SDK repo

The examples/nextjs sample is currently stale: it imports the wrong package name (@metakyc/sdk) and uses a frontend API key instead of the session-token flow. Follow this page and the SDK README, not that example.

The flow

Integrate

Install

npm install @asseteragmbh/metakyc

Create a session token on your server

Call MetaKYCSession.createToken from your backend. The secrets stay server side; the browser only ever receives the returned accessToken.

app/api/kyc/session/route.ts (server)
import { MetaKYCSession } from '@asseteragmbh/metakyc';

export async function POST(req: Request) {
  const { userId, email } = await req.json();

  const session = await MetaKYCSession.createToken({
    baseUrl: process.env.METAKYC_BASE_URL!,
    clientId: process.env.METAKYC_CLIENT_ID!,   // or tenantId
    apiKey: process.env.METAKYC_API_KEY!,       // server only
    secretKey: process.env.METAKYC_SECRET_KEY!, // server only
    externalRefId: userId,                      // scopes the token to this user
    workflowKey: 'INDIVIDUAL_KYC',
    email,
  });

  // Return only what the browser needs
  return Response.json({
    accessToken: session.accessToken,
    applicantId: session.applicantId,
    expiresInSeconds: session.expiresInSeconds,
  });
}

Wrap your app in the provider

Give the provider a getAccessToken callback that fetches the token from your server route. Do not put the API key in the browser.

app/kyc/providers.tsx (client)
'use client';
import { MetaKYCProvider } from '@asseteragmbh/metakyc';

export function KycProvider({ userId, children }: { userId: string; children: React.ReactNode }) {
  const getAccessToken = async () => {
    const res = await fetch('/api/kyc/session', {
      method: 'POST',
      body: JSON.stringify({ userId, email: /* current user */ '' }),
    });
    const { accessToken } = await res.json();
    return accessToken;
  };

  return (
    <MetaKYCProvider
      config={{
        getAccessToken,
        baseUrl: process.env.NEXT_PUBLIC_METAKYC_BASE_URL!,
        clientId: process.env.NEXT_PUBLIC_METAKYC_CLIENT_ID!,
        endpoints: { pattern: 'host-controller' },
        applicantForm: { workflowKey: 'INDIVIDUAL_KYC', externalRefId: userId },
      }}
    >
      {children}
    </MetaKYCProvider>
  );
}

Render the workflow

KycWorkflow needs only the applicantId from step 2 (theme and locale come from the provider, not props).

app/kyc/page.tsx (client)
'use client';
import { KycWorkflow } from '@asseteragmbh/metakyc';

export function Kyc({ applicantId }: { applicantId: number }) {
  return (
    <KycWorkflow
      applicantId={applicantId}
      onComplete={(result) => {/* route to success, refresh KYC status */}}
      onError={(err) => {/* show a retry */}}
    />
  );
}

Read the result

Use the onComplete callback, or the useKycWorkflow(applicantId) hook for progress.status / progress.kycStatus. The SDK also ships a KycStatusDisplay component for a ready-made status screen.

Get these right

  • Secrets are server only. apiKey and secretKey never reach the browser. The browser gets a short-lived accessToken.
  • externalRefId is required and scopes the session to one user. A mismatch is rejected (403). Use your stable user id.
  • workflowKey selects the flow (for example INDIVIDUAL_KYC).
  • KYC status is separate from the login account. Trading is gated on completed KYC, and Assetera is the responsible party for KYC/AML (see Tenancy & responsibility).

Verify against your tenant config

Concrete values (baseUrl, clientId / tenantId, available workflowKeys, the endpoints.pattern) are issued with your tenant setup. The SDK is on @asseteragmbh/metakyc v1.0.x and evolving; confirm the exact version and workflow keys with the Assetera team.

On this page