diff --git a/projects/player/src/app/app.component.ts b/projects/player/src/app/app.component.ts
index 919dfe48d88020de823a4ee0a0bcf7b79784f34a..6537a2ff9eb9332325de4568c071cd97a3aeffbb 100644
--- a/projects/player/src/app/app.component.ts
+++ b/projects/player/src/app/app.component.ts
@@ -1,18 +1,23 @@
 import { Component } from '@angular/core';
 import { FormGroup } from '@angular/forms';
-import { Unit } from '../../../common/unit';
+import { Unit, UnitPage } from '../../../common/unit';
 import { FormService } from '../../../common/form.service';
 import { FormControlElement, ValueChangeElement } from '../../../common/form';
 import { VeronaSubscriptionService } from './services/verona-subscription.service';
 import { VeronaPostService } from './services/verona-post.service';
 import { NativeEventService } from './services/native-event.service';
+import {
+  PlayerConfig, RunningState,
+  VopNavigationDeniedNotification,
+  VopStartCommand
+} from './models/verona';
 
 @Component({
   selector: 'player-aspect',
   template: `
       <form [formGroup]="form">
           <mat-tab-group mat-align-tabs="start">
-              <mat-tab *ngFor="let page of unit.pages; let i = index" label="Seite {{i+1}}">
+              <mat-tab *ngFor="let page of pages; let i = index" label="Seite {{i+1}}">
                   <app-page [parentForm]="form" [page]="page"></app-page>
               </mat-tab>
           </mat-tab-group>
@@ -24,28 +29,27 @@ import { NativeEventService } from './services/native-event.service';
 })
 export class AppComponent {
   form: FormGroup = new FormGroup({});
-  unit: Unit = {
-    pages: []
-  };
+  pages: UnitPage[] = [];
+  playerConfig!: PlayerConfig;
 
   constructor(private formService: FormService,
               private veronaSubscriptionService: VeronaSubscriptionService,
               private veronaPostService: VeronaPostService,
               private nativeEventService: NativeEventService) {
-    this.subscribe();
+    this.initSubscriptions();
     veronaPostService.sendVopReadyNotification();
   }
 
-  private subscribe(): void {
+  private initSubscriptions(): void {
     this.formService.elementValueChanged
       .subscribe((value: ValueChangeElement): void => this.onElementValueChanges(value));
     this.formService.controlAdded
       .subscribe((control: FormControlElement): void => this.addControl(control));
 
     this.veronaSubscriptionService.vopStartCommand
-      .subscribe((data: any): void => this.onStart(data));
+      .subscribe((message: VopStartCommand): void => this.onStart(message));
     this.veronaSubscriptionService.vopNavigationDeniedNotification
-      .subscribe((data: any): void => this.onNavigationDenied(data));
+      .subscribe((message: VopNavigationDeniedNotification): void => this.onNavigationDenied(message));
 
     this.nativeEventService.scrollY
       .subscribe((y: number): void => this.onScrollY(y));
@@ -53,21 +57,46 @@ export class AppComponent {
       .subscribe((focused: boolean): void => this.onFocus(focused));
   }
 
-  private onStart(data: any): void {
-    console.log('player: onStart', data);
-    this.veronaPostService.sessionId = data.sessionId;
-    this.unit = JSON.parse(data.unitDefinition);
-    // playerStartData.unitStateData = data.unitState?.dataParts?.all;
+  private get validPages():Record<string, string>[] {
+    return this.pages.map((page:UnitPage, index:number) => {
+      const validPage: Record<string, string> = {};
+      validPage[`page${index}`] = `Seite ${index + 1}`;
+      return validPage;
+    });
+  }
+
+  private onStart(message: VopStartCommand): void {
+    // eslint-disable-next-line no-console
+    console.log('player: onStart', message);
     this.initForm();
+    this.initPlayer(message);
+    const values = {
+      playerState:
+        {
+          state: 'running' as RunningState,
+          validPages: this.validPages,
+          currentPage: 'page0'
+        }
+    };
+    this.veronaPostService.sendVopStateChangedNotification(values);
   }
 
   private initForm(): void {
     this.form = new FormGroup({});
-    this.form.valueChanges.subscribe(v => this.onFormChanges(v));
+    this.form.valueChanges
+      .subscribe((formValues: any): void => this.onFormChanges(formValues));
   }
 
-  private onNavigationDenied(data: any): void {
-    console.log('player: onNavigationDenied', data);
+  private initPlayer(message: VopStartCommand): void {
+    this.veronaPostService.sessionId = message.sessionId;
+    const unit: Unit = message.unitDefinition ? JSON.parse(message.unitDefinition) : [];
+    this.pages = unit.pages;
+    this.playerConfig = message.playerConfig || {};
+  }
+
+  private onNavigationDenied(message: VopNavigationDeniedNotification): void {
+    // eslint-disable-next-line no-console
+    console.log('player: onNavigationDenied', message);
     this.form.markAllAsTouched();
   }
 
@@ -80,19 +109,27 @@ export class AppComponent {
     console.log(`Player: onElementValueChanges - ${value.id}: ${value.values[0]} -> ${value.values[1]}`);
   };
 
-  private onFormChanges(value: unknown): void {
-    const allValues: string = JSON.stringify(value);
+  private onFormChanges(formValues: unknown): void {
     // eslint-disable-next-line no-console
-    console.log('Player: emit valueChanged', allValues);
-    this.veronaPostService.sendVopStateChangedNotification(allValues);
+    console.log('player: onFormChanges', formValues);
+    // TODO: map by page and? section not all
+    const values = {
+      unitState: {
+        dataParts: {
+          all: JSON.stringify(formValues)
+        }
+      }
+    };
+    this.veronaPostService.sendVopStateChangedNotification(values);
   }
 
   private onScrollY = (y: number): void => {
+    // eslint-disable-next-line no-console
     console.log('player: onScrollY', y);
   };
 
-  // TODO
   private onFocus(focused: boolean): void {
+    // eslint-disable-next-line no-console
     console.log('player: onFocus', focused);
     this.veronaPostService.sendVopWindowFocusChangedNotification(focused);
   }
diff --git a/projects/player/src/app/models/verona.ts b/projects/player/src/app/models/verona.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0980668fb85203993d199b2b6c065090c6b0260d
--- /dev/null
+++ b/projects/player/src/app/models/verona.ts
@@ -0,0 +1,111 @@
+export type NavigationTarget = 'first' | 'last' | 'previous' | 'next' | 'end';
+
+export type RunningState = 'running' | 'stopped';
+
+export interface PlayerConfig {
+  unitNumber?: number;
+  unitTitle?: number;
+  unitId?: number;
+  stateReportPolicy?: 'none' | 'eager' | 'on-demand';
+  pagingMode?: 'separate' | 'concat-scroll' | 'concat-scroll-snap';
+  logPolicy?: 'lean' | 'rich' | 'debug' | 'disabled';
+  startPage?: string;
+  enabledNavigationTargets?: NavigationTarget[]
+}
+
+export interface UnitState {
+  dataParts?: Record<string, string>;
+  presentationProgress?: 'none' | 'some' | 'complete';
+  responseProgress?: 'none' | 'some' | 'complete';
+  unitStateDataType?: string;
+}
+
+export interface PlayerState {
+  state: RunningState ;
+  validPages?: Record<string, string>[];
+  currentPage?: string;
+}
+
+export interface LogData{
+  timeStamp: number,
+  key: string,
+  content?: string
+}
+
+export interface VopStartCommand {
+  type: 'vopStartCommand';
+  sessionId: string;
+  unitDefinition?: string;
+  unitDefinitionType?: string;
+  unitState?: UnitState;
+  playerConfig?: PlayerConfig;
+}
+
+export interface VopNavigationDeniedNotification {
+  type: 'vopNavigationDeniedNotification';
+  sessionId: string;
+  reason?: Array<'presentationIncomplete' | 'responsesIncomplete'>
+}
+
+export interface VopPageNavigationCommand {
+  type: 'vopPageNavigationCommand';
+  sessionId: string;
+  target: string;
+}
+
+export interface VopGetStateRequest {
+  type: 'vopGetStateRequest';
+  sessionId: string;
+  stop: boolean;
+}
+
+export interface VopStopCommand {
+  type: 'vopStopCommand';
+  sessionId: string;
+}
+
+export interface VopContinueCommand {
+  type: 'vopContinueCommand';
+  sessionId: string;
+}
+
+export interface VopReadyNotification {
+  type: 'vopReadyNotification';
+  apiVersion: string;
+  notSupportedApiFeatures?: string;
+  supportedUnitDefinitionTypes?: string;
+  supportedUnitStateDataTypes?: string;
+}
+
+export interface VopStateChangedNotification {
+  type: 'vopStateChangedNotification';
+  sessionId: string;
+  timeStamp: number;
+  unitState?: UnitState;
+  playerState?: PlayerState;
+  log?: LogData[];
+}
+
+export interface VopUnitNavigationRequestedNotification {
+  type: 'vopUnitNavigationRequestedNotification';
+  sessionId: string;
+  target: 'first' | 'last' | 'previous' | 'next' | 'end';
+}
+
+export interface VopWindowFocusChangedNotification {
+  type: 'vopWindowFocusChangedNotification';
+  timeStamp: number;
+  hasFocus: boolean;
+}
+
+export type VopMessage =
+  VopStartCommand |
+  VopNavigationDeniedNotification |
+  VopPageNavigationCommand |
+  VopGetStateRequest |
+  VopStopCommand |
+  VopContinueCommand |
+  VopReadyNotification |
+  VopStateChangedNotification |
+  VopWindowFocusChangedNotification |
+  VopUnitNavigationRequestedNotification;
diff --git a/projects/player/src/app/services/verona-post.service.ts b/projects/player/src/app/services/verona-post.service.ts
index 1644be7d5010d78a8a5aa2bf03e88df6f3da15ca..b4bc85fc9734d065965079282fd3b031c3d30d6f 100644
--- a/projects/player/src/app/services/verona-post.service.ts
+++ b/projects/player/src/app/services/verona-post.service.ts
@@ -1,11 +1,14 @@
 import { Inject, Injectable } from '@angular/core';
 import { DOCUMENT } from '@angular/common';
+import {
+  LogData, NavigationTarget, PlayerState, UnitState, VopMessage
+} from '../models/verona';
 
 @Injectable({
   providedIn: 'root'
 })
 export class VeronaPostService {
-  private playerMetadata!: any;
+  private readonly playerMetadata!: NamedNodeMap;
   private _sessionId!: string;
 
   constructor(@Inject(DOCUMENT) private document: Document) {
@@ -18,38 +21,46 @@ export class VeronaPostService {
 
   private isStandalone = (): boolean => window === window.parent;
 
-  private send(message: any): void {
-    // prevend posts in local dev mode
+  private send(message: VopMessage): void {
+    // prevent posts in local (dev) mode
     if (!this.isStandalone()) {
       window.parent.postMessage(message, '*');
     }
   }
 
-  sendVopStateChangedNotification(value: unknown) : void {
+  sendVopStateChangedNotification(values: {
+    unitState?: UnitState,
+    playerState?: PlayerState,
+    log?: LogData[]
+  }): void {
     this.send({
       type: 'vopStateChangedNotification',
       sessionId: this._sessionId,
       timeStamp: Date.now(),
-      unitState: {
-        dataParts: {
-          all: value
-        },
-        unitStateDataType: this.playerMetadata.getNamedItem('data-supported-unit-state-data-types').value
-      }
+      ...(values)
     });
   }
 
   sendVopReadyNotification(): void {
-    this.send({
-      type: 'vopReadyNotification',
-      apiVersion: this.playerMetadata.getNamedItem('data-api-version').value,
-      notSupportedApiFeatures: this.playerMetadata.getNamedItem('data-not-supported-api-features').value,
-      supportedUnitDefinitionTypes: this.playerMetadata.getNamedItem('data-supported-unit-definition-types').value,
-      supportedUnitStateDataTypes: this.playerMetadata.getNamedItem('data-supported-unit-state-data-types').value
-    });
+    if (this.playerMetadata) {
+      this.send({
+        type: 'vopReadyNotification',
+        apiVersion:
+          this.playerMetadata.getNamedItem('data-api-version')?.value || '',
+        notSupportedApiFeatures:
+          this.playerMetadata.getNamedItem('data-not-supported-api-features')?.value,
+        supportedUnitDefinitionTypes:
+          this.playerMetadata.getNamedItem('data-supported-unit-definition-types')?.value,
+        supportedUnitStateDataTypes:
+          this.playerMetadata.getNamedItem('data-supported-unit-state-data-types')?.value
+      });
+    } else {
+      // eslint-disable-next-line no-console
+      console.warn('player: no playerMetadata defined');
+    }
   }
 
-  sendVopUnitNavigationRequestedNotification = (target: string): void => {
+  sendVopUnitNavigationRequestedNotification = (target: NavigationTarget): void => {
     this.send({
       type: 'vopUnitNavigationRequestedNotification',
       sessionId: this._sessionId,
@@ -60,7 +71,7 @@ export class VeronaPostService {
   sendVopWindowFocusChangedNotification = (focused: boolean): void => {
     this.send({
       type: 'vopWindowFocusChangedNotification',
-      sessionId: this._sessionId,
+      timeStamp: Date.now(),
       hasFocus: focused
     });
   };
diff --git a/projects/player/src/app/services/verona-subscription.service.ts b/projects/player/src/app/services/verona-subscription.service.ts
index a192d0bd409bc1a861a9fc8f6751777fa6aeb219..78a3bbca26d4705ad6fd70c90a8a68f77ba68079 100644
--- a/projects/player/src/app/services/verona-subscription.service.ts
+++ b/projects/player/src/app/services/verona-subscription.service.ts
@@ -1,28 +1,32 @@
 import { Injectable } from '@angular/core';
 import { fromEvent, Observable, Subject } from 'rxjs';
+import { VopMessage, VopNavigationDeniedNotification, VopStartCommand } from '../models/verona';
 
 @Injectable({
   providedIn: 'root'
 })
 
 export class VeronaSubscriptionService {
-  private _vopStartCommand = new Subject<any>();
-  private _vopNavigationDeniedNotification = new Subject<any>();
+  private _vopStartCommand = new Subject<VopStartCommand>();
+  private _vopNavigationDeniedNotification = new Subject<VopNavigationDeniedNotification>();
 
   constructor() {
     fromEvent(window, 'message')
       .subscribe((e: Event): void => {
-        this.handleMessage((e as MessageEvent).data);
+        const message = (e as MessageEvent).data as VopMessage;
+        this.handleMessage(message);
       });
   }
 
-  handleMessage(messageData: any): void {
+  private handleMessage(messageData: VopMessage): void {
     switch (messageData.type) {
       case 'vopStartCommand':
+        // eslint-disable-next-line no-console
         console.log('Player: _vopStartCommand ', messageData);
         this._vopStartCommand.next(messageData);
         break;
       case 'vopNavigationDeniedNotification':
+        // eslint-disable-next-line no-console
         console.log('Player: _vopNavigationDeniedNotification ', messageData);
         this._vopNavigationDeniedNotification.next(messageData);
         break;
@@ -32,15 +36,16 @@ export class VeronaSubscriptionService {
       case 'vopStopCommand':
       case 'vopContinueCommand':
       default:
+        // eslint-disable-next-line no-console
         console.warn(`player: got message of unknown type ${messageData.type}`);
     }
   }
 
-  get vopStartCommand(): Observable<any> {
+  get vopStartCommand(): Observable<VopStartCommand> {
     return this._vopStartCommand.asObservable();
   }
 
-  get vopNavigationDeniedNotification(): Observable<any> {
+  get vopNavigationDeniedNotification(): Observable<VopNavigationDeniedNotification> {
     return this._vopNavigationDeniedNotification.asObservable();
   }
 }
diff --git a/projects/player/src/index.html b/projects/player/src/index.html
index 43c033de1cc778a7900634da5dac3c04fc00f31a..7d96da93c8fcc2b05306429f714ab6867b82065f 100644
--- a/projects/player/src/index.html
+++ b/projects/player/src/index.html
@@ -46,7 +46,13 @@
         unitState: {
           dataParts: {}
         },
-        playerConfig: {}
+        playerConfig: {
+          stateReportPolicy: 'eager',
+          pagingMode: 'separate',
+          logPolicy: 'rich',
+          startPage: 'page0',
+          enabledNavigationTargets: ['next']
+        }
       }, '*');
     }
     const input = document.getElementById('fileInput');