diff --git a/apps/agent/src/app/app.module.ts b/apps/agent/src/app/app.module.ts
index 56ad943038ed0d1c0032ffd431966a2d391714b5..77019aa51f57d8c742b9ad2278cee3a98e28ec3f 100644
--- a/apps/agent/src/app/app.module.ts
+++ b/apps/agent/src/app/app.module.ts
@@ -11,6 +11,8 @@ import {
   ledgersSchema,
   ipfsConfig,
   ipfsSchema,
+  catalogConfig,
+  catalogSchema,
 } from "@ocm-engine/config";
 import Joi from "joi";
 
@@ -19,6 +21,7 @@ const validationSchema = Joi.object({
   auth: authSchema,
   ledgers: ledgersSchema,
   ipfs: ipfsSchema,
+  catalog: catalogSchema,
 });
 
 @Module({
@@ -26,7 +29,7 @@ const validationSchema = Joi.object({
     AskarDynamicModule.forRootAsync(),
     ConfigModule.forRoot({
       isGlobal: true,
-      load: [agentConfig, authConfig, ledgersConfig, ipfsConfig],
+      load: [agentConfig, authConfig, ledgersConfig, ipfsConfig, catalogConfig],
       validationSchema,
     }),
   ],
diff --git a/libs/askar/src/agent.utils.ts b/libs/askar/src/agent.utils.ts
index 1895f51abc8a77e00f97d707330a80f62b198585..1f49aa05c58b46e25d79e703d50f9c67c776104f 100644
--- a/libs/askar/src/agent.utils.ts
+++ b/libs/askar/src/agent.utils.ts
@@ -48,6 +48,7 @@ import { anoncreds } from "@hyperledger/anoncreds-nodejs";
 import { AskarModule } from "@credo-ts/askar";
 import { ariesAskar } from "@hyperledger/aries-askar-nodejs";
 import { Key as AskarKey, KeyAlgs } from "@hyperledger/aries-askar-shared";
+import crypto from "crypto";
 import {
   catchError,
   filter,
@@ -203,6 +204,11 @@ export const generateDidWeb = async ({
   console.log(JSON.stringify(didDocumentInstance.toJSON(), null, 2));
 };
 
+export const generateRandomDidSvdx = async (agent: Agent) => {
+  const seed = crypto.randomBytes(46).toString("hex");
+  return generateDidSvdx({ agent, seed });
+};
+
 export const generateDidSvdx = async ({
   seed,
   agent,
@@ -235,6 +241,8 @@ export const generateDidSvdx = async ({
   if (!didResult.didState.didDocument) {
     throw new Error("Could not create did svdx");
   }
+
+  return didResult;
 };
 
 export const generateDidFromKey = (key: Key): string => {
diff --git a/libs/askar/src/askar-rest/rest.controller.ts b/libs/askar/src/askar-rest/rest.controller.ts
index c2d8a349c05b68c332b62fe7af8cbe629fe795eb..8ebc3eff30912744c0360b21bc697ad7a67183a2 100644
--- a/libs/askar/src/askar-rest/rest.controller.ts
+++ b/libs/askar/src/askar-rest/rest.controller.ts
@@ -17,6 +17,7 @@ import { AgentDidsService } from "../askar/services/agent.dids.service";
 import { AgentJsonldService } from "../askar/services/agent.jsonld.service";
 import { AgentOobService } from "../askar/services/agent.oob.service";
 import { AgentProofsService } from "../askar/services/agent.proofs.service";
+import { AgentOcmService } from "../askar/services/agent.ocm.service";
 import {
   CreateCredentialDefinitionRequestDto,
   OfferCredentialRequestDto,
@@ -35,6 +36,7 @@ import {
   OfferJsonCredentialRequests,
   SignJsonCredentialRequests,
   DidRecordDto,
+  RequestSenderEmailVcDto,
 } from "@ocm-engine/dtos";
 import { AllExceptionsHandler } from "./exception.handler";
 import { DidResolutionResult } from "@credo-ts/core";
@@ -53,6 +55,7 @@ export class RestController {
     private readonly agentJsonldService: AgentJsonldService,
     private readonly agentOobService: AgentOobService,
     private readonly agentProofsService: AgentProofsService,
+    private readonly agentOcmService: AgentOcmService,
   ) {}
 
   @Get("/invitations")
@@ -272,4 +275,9 @@ export class RestController {
   async resolveDid(@Body() dto: IdReqDto): Promise<DidResolutionResult> {
     return this.agentDidsService.resolve(dto.id);
   }
+
+  @Post("/ocm/request-sender-email-vc")
+  async requestSenderEmailVC(@Body() dto: RequestSenderEmailVcDto) {
+    return this.agentOcmService.requestSenderEmailVC(dto);
+  }
 }
diff --git a/libs/askar/src/askar/askar.module.ts b/libs/askar/src/askar/askar.module.ts
index 9631ba3b94d40a55606202fc8e933ce338ce6a3f..dba3185cf9737b77e68d6b689362e07d3e4021c2 100644
--- a/libs/askar/src/askar/askar.module.ts
+++ b/libs/askar/src/askar/askar.module.ts
@@ -8,6 +8,8 @@ import { AgentDidsService } from "./services/agent.dids.service";
 import { AgentJsonldService } from "./services/agent.jsonld.service";
 import { AgentOobService } from "./services/agent.oob.service";
 import { AgentProofsService } from "./services/agent.proofs.service";
+import { AgentOcmService } from "./services/agent.ocm.service";
+import { CatalogClient } from "./clients/catalog.client";
 import { ConfigModule } from "@nestjs/config";
 import { LedgersModule } from "@ocm-engine/ledgers";
 
@@ -23,6 +25,8 @@ import { LedgersModule } from "@ocm-engine/ledgers";
     AgentJsonldService,
     AgentOobService,
     AgentProofsService,
+    AgentOcmService,
+    CatalogClient,
     AskarService,
   ],
   exports: [
@@ -34,6 +38,8 @@ import { LedgersModule } from "@ocm-engine/ledgers";
     AgentJsonldService,
     AgentOobService,
     AgentProofsService,
+    AgentOcmService,
+    CatalogClient,
     AskarService,
   ],
 })
diff --git a/libs/askar/src/askar/clients/catalog.client.ts b/libs/askar/src/askar/clients/catalog.client.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9e2971ea859a4fa90353d9a69a34165ae86579a3
--- /dev/null
+++ b/libs/askar/src/askar/clients/catalog.client.ts
@@ -0,0 +1,47 @@
+import { Injectable, Logger } from "@nestjs/common";
+import { IConfCatalog } from "@ocm-engine/config";
+import { ConfigService } from "@nestjs/config";
+import axios, { AxiosError } from "axios";
+
+@Injectable()
+export class CatalogClient {
+  private readonly logger = new Logger(CatalogClient.name);
+  private catalogConfig: IConfCatalog;
+  constructor(private readonly configService: ConfigService) {
+    this.catalogConfig = this.configService.get<IConfCatalog>("catalog")!;
+  }
+
+  searchAccount = async (email: string): Promise<string | null> => {
+    this.logger.debug(`searchAccount`, email);
+    try {
+      const response = await axios.post(
+        `${this.catalogConfig.catalogUrl}/v1/accounts/search`,
+        {
+          email: email,
+        },
+      );
+      return response.data.did;
+    } catch (e) {
+      this.logger.debug("searchAccount failed", e);
+
+      if (e instanceof AxiosError && e.status === 404) {
+        return null;
+      } else {
+        throw e;
+      }
+    }
+  };
+
+  createAccount = async (email: string, didSvdx: string): Promise<void> => {
+    this.logger.debug(`createAccount`, email);
+    try {
+      await axios.post(`${this.catalogConfig.catalogUrl}/v1/accounts`, {
+        email: email,
+        did: didSvdx,
+      });
+    } catch (e) {
+      this.logger.debug("createAccount failed", e);
+      throw e;
+    }
+  };
+}
diff --git a/libs/askar/src/askar/services/agent.ocm.service.ts b/libs/askar/src/askar/services/agent.ocm.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5ef2a31efd2bb629ebae4bfa3313ddd21542db87
--- /dev/null
+++ b/libs/askar/src/askar/services/agent.ocm.service.ts
@@ -0,0 +1,137 @@
+import { Injectable, Logger } from "@nestjs/common";
+import { EntityNotFoundError, RequestSenderEmailVcDto } from "@ocm-engine/dtos";
+import { CatalogClient } from "../clients/catalog.client";
+import { generateRandomDidSvdx } from "../../agent.utils";
+import { AskarService } from "./askar.service";
+import { IConfCatalog } from "@ocm-engine/config";
+import { ConfigService } from "@nestjs/config";
+import {
+  ClaimFormat,
+  JsonTransformer,
+  W3cCredential,
+  W3cCredentialService,
+} from "@credo-ts/core";
+import { uuid } from "@credo-ts/core/build/utils/uuid";
+
+@Injectable()
+export class AgentOcmService {
+  private readonly logger = new Logger(AgentOcmService.name);
+  private activated = false;
+  constructor(
+    private readonly askar: AskarService,
+    private readonly catalogClient: CatalogClient,
+    private readonly configService: ConfigService,
+  ) {
+    const catalogConfig = this.configService.get<IConfCatalog>("catalog")!;
+    this.activated = !!catalogConfig.catalogUrl;
+  }
+
+  requestSenderEmailVC = async (
+    dto: RequestSenderEmailVcDto,
+  ): Promise<{
+    email: string;
+    did: string;
+    vc: object;
+  }> => {
+    this.ensureActivated();
+
+    this.logger.debug(`requestSenderEmailVC`, dto.email);
+    const didSvdx = await this.catalogClient.searchAccount(dto.email);
+    if (didSvdx) {
+      const record = await this.askar.agent.genericRecords.findById(
+        "svdx_vc_" + dto.email,
+      );
+      if (!record) {
+        // todo regenerate in that case?
+        throw new Error(
+          `VC not found in storage, even though the catalog has some data about it. did: ${didSvdx}, email: ${dto.email}`,
+        );
+      }
+      const vc = record.content;
+      return {
+        email: dto.email,
+        did: didSvdx,
+        vc,
+      };
+    }
+
+    const newDidSvdx = await generateRandomDidSvdx(this.askar.agent);
+
+    if (!newDidSvdx.didState.did) {
+      throw new Error("Svdx did generation failed");
+    }
+
+    const didRecords = await this.askar.agent.dids.getCreatedDids({
+      method: "svdx",
+      did: newDidSvdx.didState.did,
+    });
+    if (!didRecords.length) {
+      throw new EntityNotFoundError("Agent does not have did:svdx");
+    }
+    const svdxDid = didRecords[0];
+    const verificationMethodList =
+      svdxDid.didDocument?.verificationMethod || [];
+    if (!verificationMethodList.length) {
+      throw new EntityNotFoundError(
+        "DidDocument does not exists or contains no verification methods",
+      );
+    }
+
+    const verificationMethod = verificationMethodList[0];
+
+    const credentialRecordId = uuid();
+    const credential = JsonTransformer.fromJSON(
+      {
+        "@context": [
+          "https://www.w3.org/2018/credentials/v1",
+          "https://w3id.org/security/suites/jws-2020/v1",
+          "https://www.vereign.com/.well-known/svdx-account-schema",
+        ],
+        type: ["VerifiableCredential"],
+        id: svdxDid.did + "?uuid=" + credentialRecordId,
+        issuer: svdxDid.did,
+        issuanceDate: new Date().toISOString(),
+        credentialSubject: {
+          type: "svdx:SvdxAccount",
+          "svdx:email": dto.email,
+          "svdx:did": newDidSvdx.didState.did,
+        },
+      },
+      W3cCredential,
+    );
+
+    const w3cServ =
+      this.askar.agent.context.dependencyManager.resolve(W3cCredentialService);
+    const vc = await w3cServ.signCredential(this.askar.agent.context, {
+      format: ClaimFormat.LdpVc,
+      credential,
+      proofType: "Ed25519Signature2018",
+      verificationMethod: verificationMethod.id,
+    });
+    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+    // @ts-ignore
+    const jsonVC = vc.toJson();
+
+    // Save credential
+    await this.askar.agent.genericRecords.save({
+      id: "svdx_vc_" + dto.email,
+      content: jsonVC,
+    });
+
+    await this.catalogClient.createAccount(dto.email, svdxDid.did);
+
+    return {
+      email: dto.email,
+      did: svdxDid.did,
+      vc: jsonVC,
+    };
+  };
+
+  private ensureActivated() {
+    if (!this.activated) {
+      throw new Error(
+        "Please provide the catalog URL on startup to activate this endpoint.",
+      );
+    }
+  }
+}
diff --git a/libs/config/src/config/catalog.config.ts b/libs/config/src/config/catalog.config.ts
new file mode 100644
index 0000000000000000000000000000000000000000..bc0fd33e2916eb1082ca7cf42c5cddd3c8886db5
--- /dev/null
+++ b/libs/config/src/config/catalog.config.ts
@@ -0,0 +1,10 @@
+import { registerAs } from "@nestjs/config";
+import * as process from "process";
+import { IConfCatalog } from "../interfaces/catalog.config.interface";
+
+export const catalogConfig = registerAs(
+  "catalog",
+  (): IConfCatalog => ({
+    catalogUrl: process.env["CATALOG_URL"]!,
+  }),
+);
diff --git a/libs/config/src/index.ts b/libs/config/src/index.ts
index 0f7e567de1a8f28255f94c49e9221eda4d73e457..8e2c21aea60f2ef58ad43f718f396809dedb4863 100644
--- a/libs/config/src/index.ts
+++ b/libs/config/src/index.ts
@@ -2,13 +2,16 @@ export * from "./config/agent.config";
 export * from "./config/auth.config";
 export * from "./config/ledgers.config";
 export * from "./config/ipfs.config";
+export * from "./config/catalog.config";
 
 export * from "./interfaces/agent.config.interface";
 export * from "./interfaces/auth.config.interface";
 export * from "./interfaces/ledgers.config.interface";
 export * from "./interfaces/ipfs.config.interface";
+export * from "./interfaces/catalog.config.interface";
 
 export * from "./schemas/agent.schema";
 export * from "./schemas/auth.schema";
 export * from "./schemas/ledgers.schema";
 export * from "./schemas/ipfs.schema";
+export * from "./schemas/catalog.schema";
diff --git a/libs/config/src/interfaces/catalog.config.interface.ts b/libs/config/src/interfaces/catalog.config.interface.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7e70785ca6f208a343974453a87e78cf70f009aa
--- /dev/null
+++ b/libs/config/src/interfaces/catalog.config.interface.ts
@@ -0,0 +1,3 @@
+export interface IConfCatalog {
+  catalogUrl: string;
+}
diff --git a/libs/config/src/schemas/catalog.schema.ts b/libs/config/src/schemas/catalog.schema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e634ec71ccf59b63a85fddd13e297d1cbe12017d
--- /dev/null
+++ b/libs/config/src/schemas/catalog.schema.ts
@@ -0,0 +1,5 @@
+import Joi from "joi";
+
+export const catalogSchema = Joi.object({
+  CATALOG_URL: Joi.string(),
+});
diff --git a/libs/dtos/src/dtos/requests/request.sender.email.vc.dto.ts b/libs/dtos/src/dtos/requests/request.sender.email.vc.dto.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f75b9b63390dc5030920a7333b1cf8caf8dd36c6
--- /dev/null
+++ b/libs/dtos/src/dtos/requests/request.sender.email.vc.dto.ts
@@ -0,0 +1,7 @@
+import { IsNotEmpty, IsEmail } from "class-validator";
+
+export class RequestSenderEmailVcDto {
+  @IsEmail()
+  @IsNotEmpty()
+  email: string;
+}
diff --git a/libs/dtos/src/index.ts b/libs/dtos/src/index.ts
index d57afd18a2a2a3e109ba3b2943cb94ef9846a1e7..cedb6f7f6eb8a7f42635c3e456dde263f3ae1804 100644
--- a/libs/dtos/src/index.ts
+++ b/libs/dtos/src/index.ts
@@ -26,6 +26,7 @@ export * from "./dtos/requests/offer.credential.request.dto";
 export * from "./dtos/requests/request.proof.dto";
 export * from "./dtos/requests/make.basic.message.request.dto";
 export * from "./dtos/requests/create.invitation.request.dto";
+export * from "./dtos/requests/request.sender.email.vc.dto";
 
 export * from "./dtos/credo/w3c/credential/w3c.credential.dto";
 export * from "./dtos/credo/w3c/credential/w3c.credential-schema.dto";