diff --git a/apps/credential-manager/src/application.ts b/apps/credential-manager/src/application.ts
index c0ad214c9e168df74c7ff3f31a15253f0cbafa39..f60686bfdfb1359cffcd9c418d60ee6bd4459be6 100644
--- a/apps/credential-manager/src/application.ts
+++ b/apps/credential-manager/src/application.ts
@@ -12,6 +12,7 @@ import { natsConfig } from './config/nats.config.js';
 import { ssiConfig } from './config/ssi.config.js';
 import { validationSchema } from './config/validation.js';
 import { CredentialOffersModule } from './credential-offers/credential-offers.module.js';
+import { CredentialRequestsModule } from './credential-requests/credential-requests.module.js';
 
 @Module({
   imports: [
@@ -59,10 +60,12 @@ import { CredentialOffersModule } from './credential-offers/credential-offers.mo
     }),
 
     CredentialOffersModule,
+    CredentialRequestsModule,
 
     RouterModule.register([
       { module: HealthModule, path: '/health' },
       { module: CredentialOffersModule, path: '/credential-offers' },
+      { module: CredentialRequestsModule, path: '/credential-requests' },
     ]),
   ],
 })
diff --git a/apps/credential-manager/src/credential-offers/credential-offers.controller.ts b/apps/credential-manager/src/credential-offers/credential-offers.controller.ts
index 882d08ad48ca87f1b624f51a2ebfe7f3f55269c0..1bd6ae85733d36b6c1bd08a77a40e9b00b16ccf7 100644
--- a/apps/credential-manager/src/credential-offers/credential-offers.controller.ts
+++ b/apps/credential-manager/src/credential-offers/credential-offers.controller.ts
@@ -45,6 +45,23 @@ export class CredentialOffersController {
               ],
             },
           },
+        },
+      },
+    },
+  })
+  @ApiResponse({
+    status: HttpStatus.NOT_FOUND,
+    content: {
+      'application/json': {
+        schema: {},
+        examples: {
+          'Credential offer not found': {
+            value: {
+              statusCode: 404,
+              message: 'Credential offer not found',
+              data: null,
+            },
+          },
           'Tenant not found': {
             value: {
               statusCode: 404,
diff --git a/apps/credential-manager/src/credential-requests/__tests__/credential-requests.controller.spec.ts b/apps/credential-manager/src/credential-requests/__tests__/credential-requests.controller.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..302cc4058798f0e1bb4cb257d2d53d22b47aa914
--- /dev/null
+++ b/apps/credential-manager/src/credential-requests/__tests__/credential-requests.controller.spec.ts
@@ -0,0 +1,90 @@
+import type { TestingModule } from '@nestjs/testing';
+import type {
+  EventAnonCredsCredentialRequestGetAll,
+  EventAnonCredsCredentialRequestGetById,
+} from '@ocm/shared';
+
+import { Test } from '@nestjs/testing';
+import { Subject, of, takeUntil } from 'rxjs';
+
+import { NATS_CLIENT } from '../../common/constants.js';
+import { CredentialRequestsController } from '../credential-requests.controller.js';
+import { CredentialRequestsService } from '../credential-requests.service.js';
+
+describe('CredentialRequestsController', () => {
+  const natsClientMock = {};
+
+  let controller: CredentialRequestsController;
+  let service: CredentialRequestsService;
+
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      controllers: [CredentialRequestsController],
+      providers: [
+        { provide: NATS_CLIENT, useValue: natsClientMock },
+        CredentialRequestsService,
+      ],
+    }).compile();
+
+    controller = module.get<CredentialRequestsController>(
+      CredentialRequestsController,
+    );
+    service = module.get<CredentialRequestsService>(CredentialRequestsService);
+  });
+
+  describe('find', () => {
+    it('should return a list of credential requests', (done) => {
+      const unsubscribe$ = new Subject<void>();
+      const tenantId = 'exampleTenantId';
+      const expectedResult: EventAnonCredsCredentialRequestGetAll['data'] = [];
+
+      jest
+        .spyOn(service, 'findCredentialRequests')
+        .mockReturnValueOnce(of(expectedResult));
+
+      controller
+        .find({ tenantId })
+        .pipe(takeUntil(unsubscribe$))
+        .subscribe((result) => {
+          expect(result).toStrictEqual(expectedResult);
+
+          unsubscribe$.next();
+          unsubscribe$.complete();
+
+          done();
+        });
+    });
+  });
+
+  describe('getById', () => {
+    it('should return a credential request', (done) => {
+      const unsubscribe$ = new Subject<void>();
+      const tenantId = 'exampleTenantId';
+      const credentialRequestId = 'exampleCredentialRequestId';
+      const expectedResult: EventAnonCredsCredentialRequestGetById['data'] = {
+        blinded_ms: {},
+        blinded_ms_correctness_proof: {},
+        cred_def_id: 'cred_def_id',
+        nonce: 'nonce',
+        entropy: 'entropy',
+        prover_did: 'prover_did',
+      };
+
+      jest
+        .spyOn(service, 'getCredentialRequestById')
+        .mockReturnValueOnce(of(expectedResult));
+
+      controller
+        .getById({ credentialRequestId }, { tenantId })
+        .pipe(takeUntil(unsubscribe$))
+        .subscribe((result) => {
+          expect(result).toStrictEqual(expectedResult);
+
+          unsubscribe$.next();
+          unsubscribe$.complete();
+
+          done();
+        });
+    });
+  });
+});
diff --git a/apps/credential-manager/src/credential-requests/__tests__/credential-requests.module.spec.ts b/apps/credential-manager/src/credential-requests/__tests__/credential-requests.module.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7fcd088315f73bfcf6cfc81f4e3c895705b58092
--- /dev/null
+++ b/apps/credential-manager/src/credential-requests/__tests__/credential-requests.module.spec.ts
@@ -0,0 +1,41 @@
+import { ClientsModule } from '@nestjs/microservices';
+import { Test } from '@nestjs/testing';
+
+import { NATS_CLIENT } from '../../common/constants.js';
+import { CredentialRequestsController } from '../credential-requests.controller.js';
+import { CredentialRequestsModule } from '../credential-requests.module.js';
+import { CredentialRequestsService } from '../credential-requests.service.js';
+
+describe('CredentialRequestsModule', () => {
+  let credentialRequestsController: CredentialRequestsController;
+  let credentialRequestsService: CredentialRequestsService;
+
+  beforeEach(async () => {
+    const moduleRef = await Test.createTestingModule({
+      imports: [
+        ClientsModule.registerAsync({
+          isGlobal: true,
+          clients: [{ name: NATS_CLIENT, useFactory: () => ({}) }],
+        }),
+        CredentialRequestsModule,
+      ],
+    }).compile();
+
+    credentialRequestsController = moduleRef.get<CredentialRequestsController>(
+      CredentialRequestsController,
+    );
+    credentialRequestsService = moduleRef.get<CredentialRequestsService>(
+      CredentialRequestsService,
+    );
+  });
+
+  it('should be defined', () => {
+    expect(credentialRequestsController).toBeDefined();
+    expect(credentialRequestsController).toBeInstanceOf(
+      CredentialRequestsController,
+    );
+
+    expect(credentialRequestsService).toBeDefined();
+    expect(credentialRequestsService).toBeInstanceOf(CredentialRequestsService);
+  });
+});
diff --git a/apps/credential-manager/src/credential-requests/__tests__/credential-requests.service.spec.ts b/apps/credential-manager/src/credential-requests/__tests__/credential-requests.service.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a9a8d844eb55d25548ccb150edac1d6b5a42dcbc
--- /dev/null
+++ b/apps/credential-manager/src/credential-requests/__tests__/credential-requests.service.spec.ts
@@ -0,0 +1,83 @@
+import type { TestingModule } from '@nestjs/testing';
+
+import { Test } from '@nestjs/testing';
+import { EventAnonCredsCredentialRequestGetAll } from '@ocm/shared';
+import { Subject, of, takeUntil } from 'rxjs';
+
+import { NATS_CLIENT } from '../../common/constants.js';
+import { CredentialRequestsService } from '../credential-requests.service.js';
+
+describe('CredentialRequestsService', () => {
+  const natsClientMock = { send: jest.fn() };
+  let service: CredentialRequestsService;
+
+  beforeEach(async () => {
+    const module: TestingModule = await Test.createTestingModule({
+      providers: [
+        { provide: NATS_CLIENT, useValue: natsClientMock },
+        CredentialRequestsService,
+      ],
+    }).compile();
+
+    service = module.get<CredentialRequestsService>(CredentialRequestsService);
+  });
+
+  describe('findCredentialRequests', () => {
+    it('should call the natsClient send method with the correct arguments', (done) => {
+      const unsubscribe$ = new Subject<void>();
+      const tenantId = 'tenantId';
+      const expectedResult: EventAnonCredsCredentialRequestGetAll['data'] = [];
+
+      natsClientMock.send.mockReturnValueOnce(
+        of(new EventAnonCredsCredentialRequestGetAll(expectedResult, tenantId)),
+      );
+
+      service
+        .findCredentialRequests(tenantId)
+        .pipe(takeUntil(unsubscribe$))
+        .subscribe((result) => {
+          expect(natsClientMock.send).toHaveBeenCalledWith(
+            EventAnonCredsCredentialRequestGetAll.token,
+            { tenantId },
+          );
+
+          expect(result).toStrictEqual(expectedResult);
+
+          unsubscribe$.next();
+          unsubscribe$.complete();
+
+          done();
+        });
+    });
+  });
+
+  describe('getCredentialRequestById', () => {
+    it('should call the natsClient send method with the correct arguments', (done) => {
+      const unsubscribe$ = new Subject<void>();
+      const tenantId = 'tenantId';
+      const credentialRequestId = 'credentialRequestId';
+      const expectedResult: EventAnonCredsCredentialRequestGetAll['data'] = [];
+
+      natsClientMock.send.mockReturnValueOnce(
+        of(new EventAnonCredsCredentialRequestGetAll(expectedResult, tenantId)),
+      );
+
+      service
+        .getCredentialRequestById(tenantId, credentialRequestId)
+        .pipe(takeUntil(unsubscribe$))
+        .subscribe((result) => {
+          expect(natsClientMock.send).toHaveBeenCalledWith(
+            EventAnonCredsCredentialRequestGetAll.token,
+            { tenantId, credentialRequestId },
+          );
+
+          expect(result).toStrictEqual(expectedResult);
+
+          unsubscribe$.next();
+          unsubscribe$.complete();
+
+          done();
+        });
+    });
+  });
+});
diff --git a/apps/credential-manager/src/credential-requests/credential-requests.controller.ts b/apps/credential-manager/src/credential-requests/credential-requests.controller.ts
new file mode 100644
index 0000000000000000000000000000000000000000..99297fdf950fcc017bdb1330a356a6f6e07f8ee9
--- /dev/null
+++ b/apps/credential-manager/src/credential-requests/credential-requests.controller.ts
@@ -0,0 +1,186 @@
+import {
+  Controller,
+  Get,
+  HttpStatus,
+  Param,
+  Query,
+  UseInterceptors,
+  UsePipes,
+  ValidationPipe,
+} from '@nestjs/common';
+import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
+import { MultitenancyParams, ResponseFormatInterceptor } from '@ocm/shared';
+
+import { CredentialRequestsService } from './credential-requests.service.js';
+import { GetByIdParams } from './dto/get-by-id.dto.js';
+
+@Controller()
+@UsePipes(new ValidationPipe({ transform: true, whitelist: true }))
+@UseInterceptors(ResponseFormatInterceptor)
+@ApiTags('Credential Requests')
+export class CredentialRequestsController {
+  public constructor(private readonly service: CredentialRequestsService) {}
+
+  @Get()
+  @ApiOperation({
+    summary: 'Fetch a list of credential requests',
+    description:
+      'This call provides a list of credential requests for a given tenant',
+  })
+  @ApiResponse({
+    status: HttpStatus.OK,
+    description: 'Credential requests fetched successfully',
+    content: {
+      'application/json': {
+        schema: {},
+        examples: {
+          'Credential requests fetched successfully': {
+            value: {
+              statusCode: 200,
+              message: 'Credential requests fetched successfully',
+              data: [
+                {
+                  id: '71b784a3',
+                },
+              ],
+            },
+          },
+          'Tenant not found': {
+            value: {
+              statusCode: 404,
+              message: 'Tenant not found',
+              data: null,
+            },
+          },
+        },
+      },
+    },
+  })
+  @ApiResponse({
+    status: HttpStatus.NOT_FOUND,
+    content: {
+      'application/json': {
+        schema: {},
+        examples: {
+          'Credential request not found': {
+            value: {
+              statusCode: 404,
+              message: 'Credential request not found',
+              data: null,
+            },
+          },
+          'Tenant not found': {
+            value: {
+              statusCode: 404,
+              message: 'Tenant not found',
+              data: null,
+            },
+          },
+        },
+      },
+    },
+  })
+  @ApiResponse({
+    status: HttpStatus.INTERNAL_SERVER_ERROR,
+    description: 'Internal server error',
+    content: {
+      'application/json': {
+        schema: {},
+        examples: {
+          'Internal server error': {
+            value: {
+              statusCode: 500,
+              message: 'Internal server error',
+              data: null,
+            },
+          },
+        },
+      },
+    },
+  })
+  public find(@Query() { tenantId }: MultitenancyParams) {
+    return this.service.findCredentialRequests(tenantId);
+  }
+
+  @Get(':id')
+  @ApiOperation({
+    summary: 'Fetch a credential request by id',
+    description:
+      'This call provides a credential request for a given tenant by id',
+  })
+  @ApiResponse({
+    status: HttpStatus.OK,
+    description: 'Credential request fetched successfully',
+    content: {
+      'application/json': {
+        schema: {},
+        examples: {
+          'Credential request fetched successfully': {
+            value: {
+              statusCode: 200,
+              message: 'Credential request fetched successfully',
+              data: {
+                id: '71b784a3',
+              },
+            },
+          },
+          'Tenant not found': {
+            value: {
+              statusCode: 404,
+              message: 'Tenant not found',
+              data: null,
+            },
+          },
+        },
+      },
+    },
+  })
+  @ApiResponse({
+    status: HttpStatus.NOT_FOUND,
+    content: {
+      'application/json': {
+        schema: {},
+        examples: {
+          'Credential request not found': {
+            value: {
+              statusCode: 404,
+              message: 'Credential request not found',
+              data: null,
+            },
+          },
+          'Tenant not found': {
+            value: {
+              statusCode: 404,
+              message: 'Tenant not found',
+              data: null,
+            },
+          },
+        },
+      },
+    },
+  })
+  @ApiResponse({
+    status: HttpStatus.INTERNAL_SERVER_ERROR,
+    description: 'Internal server error',
+    content: {
+      'application/json': {
+        schema: {},
+        examples: {
+          'Internal server error': {
+            value: {
+              statusCode: 500,
+              message: 'Internal server error',
+              data: null,
+            },
+          },
+        },
+      },
+    },
+  })
+  public getById(
+    @Param() { credentialRequestId }: GetByIdParams,
+    @Query() { tenantId }: MultitenancyParams,
+  ) {
+    return this.service.getCredentialRequestById(tenantId, credentialRequestId);
+  }
+}
diff --git a/apps/credential-manager/src/credential-requests/credential-requests.module.ts b/apps/credential-manager/src/credential-requests/credential-requests.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..af559d79bd371d0d0b848ae77f27c89f087b8091
--- /dev/null
+++ b/apps/credential-manager/src/credential-requests/credential-requests.module.ts
@@ -0,0 +1,10 @@
+import { Module } from '@nestjs/common';
+
+import { CredentialRequestsController } from './credential-requests.controller.js';
+import { CredentialRequestsService } from './credential-requests.service.js';
+
+@Module({
+  providers: [CredentialRequestsService],
+  controllers: [CredentialRequestsController],
+})
+export class CredentialRequestsModule {}
diff --git a/apps/credential-manager/src/credential-requests/credential-requests.service.ts b/apps/credential-manager/src/credential-requests/credential-requests.service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..81675508bb0135a679f2136b031a7bb2eba64d0f
--- /dev/null
+++ b/apps/credential-manager/src/credential-requests/credential-requests.service.ts
@@ -0,0 +1,43 @@
+import type {
+  EventAnonCredsCredentialRequestGetAllInput,
+  EventAnonCredsCredentialRequestGetById,
+  EventAnonCredsCredentialRequestGetByIdInput,
+} from '@ocm/shared';
+
+import { Inject, Injectable } from '@nestjs/common';
+import { ClientProxy } from '@nestjs/microservices';
+import { EventAnonCredsCredentialRequestGetAll } from '@ocm/shared';
+import { map } from 'rxjs';
+
+import { NATS_CLIENT } from '../common/constants.js';
+
+@Injectable()
+export class CredentialRequestsService {
+  public constructor(
+    @Inject(NATS_CLIENT) private readonly natsClient: ClientProxy,
+  ) {}
+
+  public findCredentialRequests(tenantId: string) {
+    return this.natsClient
+      .send<
+        EventAnonCredsCredentialRequestGetAll,
+        EventAnonCredsCredentialRequestGetAllInput
+      >(EventAnonCredsCredentialRequestGetAll.token, { tenantId })
+      .pipe(map(({ data }) => data));
+  }
+
+  public getCredentialRequestById(
+    tenantId: string,
+    credentialRequestId: string,
+  ) {
+    return this.natsClient
+      .send<
+        EventAnonCredsCredentialRequestGetById,
+        EventAnonCredsCredentialRequestGetByIdInput
+      >(EventAnonCredsCredentialRequestGetAll.token, {
+        tenantId,
+        credentialRequestId,
+      })
+      .pipe(map(({ data }) => data));
+  }
+}
diff --git a/apps/credential-manager/src/credential-requests/dto/get-by-id.dto.ts b/apps/credential-manager/src/credential-requests/dto/get-by-id.dto.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9c3e323437fe7c0cfaffb4b295d30540f8581623
--- /dev/null
+++ b/apps/credential-manager/src/credential-requests/dto/get-by-id.dto.ts
@@ -0,0 +1,12 @@
+import { ApiProperty } from '@nestjs/swagger';
+import { IsNotEmpty, IsString } from 'class-validator';
+
+export class GetByIdParams {
+  @IsString()
+  @IsNotEmpty()
+  @ApiProperty({
+    description: 'The credential request ID to retrieve',
+    format: 'string',
+  })
+  public credentialRequestId: string;
+}
diff --git a/apps/shared/src/events/credentialEvents.ts b/apps/shared/src/events/credentialEvents.ts
index 32ed92aaffc305cd5011a7be238647b62f3fb62f..5fbe8aa493f4ba9e0683224a9bf8ab6d1d0f4827 100644
--- a/apps/shared/src/events/credentialEvents.ts
+++ b/apps/shared/src/events/credentialEvents.ts
@@ -7,11 +7,11 @@ import {
 
 import { BaseEvent } from './baseEvents.js';
 
-export type EventDidcommAnonCredsCredentialsGetAllInput = BaseEventInput;
-export class EventDidcommAnonCredsCredentialsGetAll extends BaseEvent<
+export type EventAnonCredsCredentialsGetAllInput = BaseEventInput;
+export class EventAnonCredsCredentialsGetAll extends BaseEvent<
   Array<CredentialExchangeRecord>
 > {
-  public static token = 'didcomm.anoncreds.credentials.getAll';
+  public static token = 'anoncreds.credentials.getAll';
 
   public get instance() {
     return this.data.map((d) =>
@@ -19,8 +19,8 @@ export class EventDidcommAnonCredsCredentialsGetAll extends BaseEvent<
     );
   }
 
-  public static fromEvent(e: EventDidcommAnonCredsCredentialsGetAll) {
-    return new EventDidcommAnonCredsCredentialsGetAll(
+  public static fromEvent(e: EventAnonCredsCredentialsGetAll) {
+    return new EventAnonCredsCredentialsGetAll(
       e.data,
       e.tenantId,
       e.id,
@@ -30,11 +30,11 @@ export class EventDidcommAnonCredsCredentialsGetAll extends BaseEvent<
   }
 }
 
-export type EventDidcommAnonCredsCredentialsGetByIdInput = BaseEventInput<{
+export type EventAnonCredsCredentialsGetByIdInput = BaseEventInput<{
   credentialRecordId: string;
 }>;
-export class EventDidcommAnonCredsCredentialsGetById extends BaseEvent<CredentialExchangeRecord | null> {
-  public static token = 'didcomm.anoncreds.credentials.getById';
+export class EventAnonCredsCredentialsGetById extends BaseEvent<CredentialExchangeRecord | null> {
+  public static token = 'anoncreds.credentials.getById';
 
   public get instance() {
     return this.data
@@ -42,8 +42,8 @@ export class EventDidcommAnonCredsCredentialsGetById extends BaseEvent<Credentia
       : null;
   }
 
-  public static fromEvent(e: EventDidcommAnonCredsCredentialsGetById) {
-    return new EventDidcommAnonCredsCredentialsGetById(
+  public static fromEvent(e: EventAnonCredsCredentialsGetById) {
+    return new EventAnonCredsCredentialsGetById(
       e.data,
       e.tenantId,
       e.id,
@@ -97,3 +97,20 @@ export class EventDidcommAnonCredsCredentialsOfferToSelf extends BaseEvent<Crede
     );
   }
 }
+
+export type EventAnonCredsCredentialsDeleteByIdInput = BaseEventInput<{
+  credentialRecordId: string;
+}>;
+export class EventAnonCredsCredentialsDeleteById extends BaseEvent {
+  public static token = 'anoncreds.credentials.offerToSelf.deleteById';
+
+  public static fromEvent(e: EventAnonCredsCredentialsDeleteById) {
+    return new EventAnonCredsCredentialsDeleteById(
+      e.data,
+      e.tenantId,
+      e.id,
+      e.type,
+      e.timestamp,
+    );
+  }
+}
diff --git a/apps/shared/src/events/credentialOfferEvents.ts b/apps/shared/src/events/credentialOfferEvents.ts
index d120f84048244d20cbcc87d3bf96966b8b58725b..63e9eb15e81cc97ef0c9a264226b5c893e21a497 100644
--- a/apps/shared/src/events/credentialOfferEvents.ts
+++ b/apps/shared/src/events/credentialOfferEvents.ts
@@ -1,12 +1,12 @@
 import type { BaseEventInput } from './baseEvents.js';
-import type { AnonCredsCredentialOffer } from '@aries-framework/anoncreds';
+import type { CredentialExchangeRecord } from '@aries-framework/core';
 
 import { BaseEvent } from './baseEvents.js';
 
 export type EventAnonCredsCredentialOfferGetAllInput = BaseEventInput;
 
 export class EventAnonCredsCredentialOfferGetAll extends BaseEvent<
-  Array<AnonCredsCredentialOffer>
+  Array<CredentialExchangeRecord>
 > {
   public static token = 'anoncreds.credentialOffers.getAll';
 
@@ -29,7 +29,7 @@ export type EventAnonCredsCredentialOfferGetByIdInput = BaseEventInput & {
   credentialOfferId: string;
 };
 
-export class EventAnonCredsCredentialOfferGetById extends BaseEvent<AnonCredsCredentialOffer | null> {
+export class EventAnonCredsCredentialOfferGetById extends BaseEvent<CredentialExchangeRecord | null> {
   public static token = 'anoncreds.credentialOffers.getById';
 
   public get instance() {
diff --git a/apps/shared/src/events/credentialRequestEvents.ts b/apps/shared/src/events/credentialRequestEvents.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9daefa1066c768641d71f5968464cd40ee9c9481
--- /dev/null
+++ b/apps/shared/src/events/credentialRequestEvents.ts
@@ -0,0 +1,48 @@
+import type { BaseEventInput } from './baseEvents.js';
+import type { CredentialExchangeRecord } from '@aries-framework/core';
+
+import { BaseEvent } from './baseEvents.js';
+
+export type EventAnonCredsCredentialRequestGetAllInput = BaseEventInput;
+
+export class EventAnonCredsCredentialRequestGetAll extends BaseEvent<
+  Array<CredentialExchangeRecord>
+> {
+  public static token = 'anoncreds.credentialRequests.getAll';
+
+  public get instance() {
+    return this.data;
+  }
+
+  public static fromEvent(e: EventAnonCredsCredentialRequestGetAll) {
+    return new EventAnonCredsCredentialRequestGetAll(
+      e.data,
+      e.tenantId,
+      e.id,
+      e.type,
+      e.timestamp,
+    );
+  }
+}
+
+export type EventAnonCredsCredentialRequestGetByIdInput = BaseEventInput & {
+  credentialRequestId: string;
+};
+
+export class EventAnonCredsCredentialRequestGetById extends BaseEvent<CredentialExchangeRecord | null> {
+  public static token = 'anoncreds.credentialRequests.getById';
+
+  public get instance() {
+    return this.data;
+  }
+
+  public static fromEvent(e: EventAnonCredsCredentialRequestGetById) {
+    return new EventAnonCredsCredentialRequestGetById(
+      e.data,
+      e.tenantId,
+      e.id,
+      e.type,
+      e.timestamp,
+    );
+  }
+}
diff --git a/apps/shared/src/index.ts b/apps/shared/src/index.ts
index 7e5e2824e92af93cf89cd6432a613c83c0f3a454..20c9faf786512da49c496a8d717ff643e430242b 100644
--- a/apps/shared/src/index.ts
+++ b/apps/shared/src/index.ts
@@ -11,6 +11,7 @@ export * from './events/schemaEvents.js';
 export * from './events/credentialDefinitionEvents.js';
 export * from './events/credentialEvents.js';
 export * from './events/credentialOfferEvents.js';
+export * from './events/credentialRequestEvents.js';
 
 export * from './dto/pagination-params.dto.js';
 export * from './dto/multitenancy-params.dto.js';
diff --git a/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.controller.ts b/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.controller.ts
index 1cef75b483beddd9ff786a9b095c3402a2349e33..c0caea39567acc467d11c84c9fcfd18654f51466 100644
--- a/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.controller.ts
+++ b/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.controller.ts
@@ -1,14 +1,20 @@
 import { Controller } from '@nestjs/common';
 import { MessagePattern } from '@nestjs/microservices';
 import {
-  EventDidcommAnonCredsCredentialsGetAll,
-  EventDidcommAnonCredsCredentialsGetAllInput,
-  EventDidcommAnonCredsCredentialsGetById,
-  EventDidcommAnonCredsCredentialsGetByIdInput,
+  EventAnonCredsCredentialsGetAll,
+  EventAnonCredsCredentialsGetAllInput,
+  EventAnonCredsCredentialsGetById,
+  EventAnonCredsCredentialsGetByIdInput,
   EventDidcommAnonCredsCredentialsOffer,
   EventDidcommAnonCredsCredentialsOfferInput,
   EventDidcommAnonCredsCredentialsOfferToSelfInput,
   EventDidcommAnonCredsCredentialsOfferToSelf,
+  EventAnonCredsCredentialOfferGetAll,
+  EventAnonCredsCredentialOfferGetAllInput,
+  EventAnonCredsCredentialRequestGetAll,
+  EventAnonCredsCredentialRequestGetAllInput,
+  EventAnonCredsCredentialsDeleteById,
+  EventAnonCredsCredentialsDeleteByIdInput,
 } from '@ocm/shared';
 
 import { AnonCredsCredentialsService } from './anoncredsCredentials.service.js';
@@ -17,26 +23,56 @@ import { AnonCredsCredentialsService } from './anoncredsCredentials.service.js';
 export class AnonCredsCredentialsController {
   public constructor(private credentialsService: AnonCredsCredentialsService) {}
 
-  @MessagePattern(EventDidcommAnonCredsCredentialsGetAll.token)
+  @MessagePattern(EventAnonCredsCredentialsGetAll.token)
   public async getAll(
-    options: EventDidcommAnonCredsCredentialsGetAllInput,
-  ): Promise<EventDidcommAnonCredsCredentialsGetAll> {
-    return new EventDidcommAnonCredsCredentialsGetAll(
+    options: EventAnonCredsCredentialsGetAllInput,
+  ): Promise<EventAnonCredsCredentialsGetAll> {
+    return new EventAnonCredsCredentialsGetAll(
       await this.credentialsService.getAll(options),
       options.tenantId,
     );
   }
 
-  @MessagePattern(EventDidcommAnonCredsCredentialsGetById.token)
+  @MessagePattern(EventAnonCredsCredentialOfferGetAll.token)
+  public async getAllOffers(
+    options: EventAnonCredsCredentialOfferGetAllInput,
+  ): Promise<EventAnonCredsCredentialOfferGetAll> {
+    return new EventAnonCredsCredentialOfferGetAll(
+      await this.credentialsService.getAllOffers(options),
+      options.tenantId,
+    );
+  }
+
+  @MessagePattern(EventAnonCredsCredentialRequestGetAll.token)
+  public async getAllRequests(
+    options: EventAnonCredsCredentialRequestGetAllInput,
+  ): Promise<EventAnonCredsCredentialRequestGetAll> {
+    return new EventAnonCredsCredentialRequestGetAll(
+      await this.credentialsService.getAllRequests(options),
+      options.tenantId,
+    );
+  }
+
+  @MessagePattern(EventAnonCredsCredentialsGetById.token)
   public async getById(
-    options: EventDidcommAnonCredsCredentialsGetByIdInput,
-  ): Promise<EventDidcommAnonCredsCredentialsGetById> {
-    return new EventDidcommAnonCredsCredentialsGetById(
+    options: EventAnonCredsCredentialsGetByIdInput,
+  ): Promise<EventAnonCredsCredentialsGetById> {
+    return new EventAnonCredsCredentialsGetById(
       await this.credentialsService.getById(options),
       options.tenantId,
     );
   }
 
+  @MessagePattern(EventAnonCredsCredentialsDeleteById.token)
+  public async deleteById(
+    options: EventAnonCredsCredentialsDeleteByIdInput,
+  ): Promise<EventAnonCredsCredentialsDeleteById> {
+    return new EventAnonCredsCredentialsDeleteById(
+      await this.credentialsService.deleteById(options),
+      options.tenantId,
+    );
+  }
+
   @MessagePattern(EventDidcommAnonCredsCredentialsOffer.token)
   public async offer(
     options: EventDidcommAnonCredsCredentialsOfferInput,
diff --git a/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.service.ts b/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.service.ts
index 3eb52b6e61e023f4deb42ebefbc8ff500af4cc99..a1aa04b633c5bb454e2cb7e72b81f4935e48d586 100644
--- a/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.service.ts
+++ b/apps/ssi-abstraction/src/agent/anoncredsCredentials/anoncredsCredentials.service.ts
@@ -1,15 +1,27 @@
 import type {
-  EventDidcommAnonCredsCredentialsGetAllInput,
-  EventDidcommAnonCredsCredentialsGetByIdInput,
+  EventAnonCredsCredentialRequestGetByIdInput,
+  EventAnonCredsCredentialOfferGetAllInput,
+  EventAnonCredsCredentialOfferGetById,
+  EventAnonCredsCredentialOfferGetByIdInput,
+  EventAnonCredsCredentialRequestGetAllInput,
+  EventAnonCredsCredentialsGetAllInput,
+  EventAnonCredsCredentialsGetByIdInput,
   EventDidcommAnonCredsCredentialsOfferInput,
   EventDidcommAnonCredsCredentialsOfferToSelfInput,
+  EventAnonCredsCredentialRequestGetById,
+  EventDidcommAnonCredsCredentialsOffer,
+  EventDidcommAnonCredsCredentialsOfferToSelf,
+  EventAnonCredsCredentialsGetById,
+  EventAnonCredsCredentialRequestGetAll,
+  EventAnonCredsCredentialOfferGetAll,
+  EventAnonCredsCredentialsGetAll,
+  EventAnonCredsCredentialsDeleteByIdInput,
+  EventAnonCredsCredentialsDeleteById,
 } from '@ocm/shared';
 
-import {
-  AutoAcceptCredential,
-  type CredentialExchangeRecord,
-} from '@aries-framework/core';
+import { AutoAcceptCredential, CredentialState } from '@aries-framework/core';
 import { Injectable } from '@nestjs/common';
+import { logger } from '@ocm/shared';
 
 import { MetadataTokens } from '../../common/constants.js';
 import { WithTenantService } from '../withTenantService.js';
@@ -20,29 +32,121 @@ export class AnonCredsCredentialsService {
 
   public async getAll({
     tenantId,
-  }: EventDidcommAnonCredsCredentialsGetAllInput): Promise<
-    Array<CredentialExchangeRecord>
+  }: EventAnonCredsCredentialsGetAllInput): Promise<
+    EventAnonCredsCredentialsGetAll['data']
   > {
     return this.withTenantService.invoke(tenantId, (t) =>
       t.credentials.getAll(),
     );
   }
 
+  public async getAllOffers({
+    tenantId,
+  }: EventAnonCredsCredentialOfferGetAllInput): Promise<
+    EventAnonCredsCredentialOfferGetAll['data']
+  > {
+    return this.withTenantService.invoke(tenantId, (t) =>
+      t.credentials.findAllByQuery({
+        $or: [
+          { state: CredentialState.OfferSent },
+          { state: CredentialState.OfferReceived },
+        ],
+      }),
+    );
+  }
+
+  public async getAllRequests({
+    tenantId,
+  }: EventAnonCredsCredentialRequestGetAllInput): Promise<
+    EventAnonCredsCredentialRequestGetAll['data']
+  > {
+    return this.withTenantService.invoke(tenantId, (t) =>
+      t.credentials.findAllByQuery({
+        $or: [
+          { state: CredentialState.RequestSent },
+          { state: CredentialState.RequestReceived },
+        ],
+      }),
+    );
+  }
+
+  public async deleteById({
+    tenantId,
+    credentialRecordId,
+  }: EventAnonCredsCredentialsDeleteByIdInput): Promise<
+    EventAnonCredsCredentialsDeleteById['data']
+  > {
+    return this.withTenantService.invoke(tenantId, async (t) => {
+      await t.credentials.deleteById(credentialRecordId);
+      return {};
+    });
+  }
+
   public async getById({
     tenantId,
     credentialRecordId,
-  }: EventDidcommAnonCredsCredentialsGetByIdInput): Promise<CredentialExchangeRecord | null> {
+  }: EventAnonCredsCredentialsGetByIdInput): Promise<
+    EventAnonCredsCredentialsGetById['data']
+  > {
     return this.withTenantService.invoke(tenantId, (t) =>
       t.credentials.findById(credentialRecordId),
     );
   }
 
+  public async getOfferById({
+    tenantId,
+    credentialOfferId,
+  }: EventAnonCredsCredentialOfferGetByIdInput): Promise<
+    EventAnonCredsCredentialOfferGetById['data']
+  > {
+    return this.withTenantService.invoke(tenantId, async (t) => {
+      const credential = await t.credentials.findById(credentialOfferId);
+
+      if (
+        credential &&
+        credential.state !== CredentialState.OfferSent &&
+        credential.state !== CredentialState.OfferReceived
+      ) {
+        logger.warn(
+          `Credential '${credentialOfferId}' does exist, but is not in offer state. Actual state: ${credential.state}`,
+        );
+      }
+
+      return credential;
+    });
+  }
+
+  public async getRequestById({
+    tenantId,
+    credentialRequestId,
+  }: EventAnonCredsCredentialRequestGetByIdInput): Promise<
+    EventAnonCredsCredentialRequestGetById['data']
+  > {
+    return this.withTenantService.invoke(tenantId, async (t) => {
+      const credential = await t.credentials.findById(credentialRequestId);
+
+      if (
+        credential &&
+        credential.state !== CredentialState.RequestSent &&
+        credential.state !== CredentialState.RequestReceived
+      ) {
+        logger.warn(
+          `Credential '${credentialRequestId}' does exist, but is not in a request state. Actual state: ${credential.state}`,
+        );
+      }
+
+      return credential;
+    });
+  }
+
   public async offer({
     tenantId,
     connectionId,
     credentialDefinitionId,
     attributes,
-  }: EventDidcommAnonCredsCredentialsOfferInput): Promise<CredentialExchangeRecord> {
+  }: EventDidcommAnonCredsCredentialsOfferInput): Promise<
+    EventDidcommAnonCredsCredentialsOffer['data']
+  > {
     return this.withTenantService.invoke(tenantId, (t) =>
       t.credentials.offerCredential({
         protocolVersion: 'v2',
@@ -58,7 +162,9 @@ export class AnonCredsCredentialsService {
     tenantId,
     credentialDefinitionId,
     attributes,
-  }: EventDidcommAnonCredsCredentialsOfferToSelfInput): Promise<CredentialExchangeRecord> {
+  }: EventDidcommAnonCredsCredentialsOfferToSelfInput): Promise<
+    EventDidcommAnonCredsCredentialsOfferToSelf['data']
+  > {
     return this.withTenantService.invoke(tenantId, async (t) => {
       const connections = await t.connections.getAll();
       const connection = connections.find((c) => {