diff --git a/goofy-client/libs/binary-file-shared/src/index.ts b/goofy-client/libs/binary-file-shared/src/index.ts
index 98668608fffec2553c79e128f2e106b925cdefa1..bffe195cf7eb6a011c7efeefa83563e153bea2ad 100644
--- a/goofy-client/libs/binary-file-shared/src/index.ts
+++ b/goofy-client/libs/binary-file-shared/src/index.ts
@@ -1,4 +1,7 @@
+export * from './lib/+state/binary-file.actions';
+export * from './lib/+state/binary-file.reducer';
 export * from './lib/binary-file-shared.module';
 export * from './lib/binary-file.linkrel';
 export * from './lib/binary-file.model';
 export * from './lib/binary-file.service';
+
diff --git a/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.actions.ts b/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.actions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f0a6f96f0ea9b47204178b519a985c3ec33b577f
--- /dev/null
+++ b/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.actions.ts
@@ -0,0 +1,21 @@
+import { ApiError, ApiErrorAction, TypedActionCreatorWithProps } from '@goofy-client/tech-shared';
+import { createAction, props } from '@ngrx/store';
+import { TypedAction } from '@ngrx/store/src/models';
+import { ResourceUri } from '@ngxp/rest';
+
+export interface SaveBinaryFileAsPdfAction {
+	fileData: Blob
+	fileName: string
+}
+
+export interface DownloadBinaryFileAsPdfAction {
+	uri: ResourceUri
+	fileName: string,
+	successAction: () => DownloadBinaryFileSuccessAction & TypedAction<string>,
+	failureAction: (apiError: ApiError) => ApiErrorAction & TypedAction<string>,
+}
+
+export interface DownloadBinaryFileSuccessAction { }
+
+export const downloadPdf: TypedActionCreatorWithProps<DownloadBinaryFileAsPdfAction> = createAction('[BinaryFile] Download pdf file', props<DownloadBinaryFileAsPdfAction>());
+export const saveAsPdf: TypedActionCreatorWithProps<SaveBinaryFileAsPdfAction> = createAction('[BinaryFile/API] Save file as pdf', props<SaveBinaryFileAsPdfAction>());
\ No newline at end of file
diff --git a/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.effects.spec.ts b/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.effects.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6a20c2721819ee1ac79c6945a5e6a2c34073b3fa
--- /dev/null
+++ b/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.effects.spec.ts
@@ -0,0 +1,92 @@
+import { TestBed } from '@angular/core/testing';
+import faker from '@faker-js/faker';
+import { TypedActionCreator } from '@goofy-client/tech-shared';
+import { Mock, mock } from '@goofy-client/test-utils';
+import { provideMockActions } from '@ngrx/effects/testing';
+import { Action, createAction } from '@ngrx/store';
+import { provideMockStore } from '@ngrx/store/testing';
+import { ResourceUri } from '@ngxp/rest';
+import { NxModule } from '@nrwl/angular';
+import { hot } from 'jasmine-marbles';
+import { cold } from 'jest-marbles';
+import { Observable, of } from 'rxjs';
+import { BinaryFileRepository } from '../binary-file.repository';
+import { BinaryFileEffects } from './binary-file.effects';
+
+import * as BinaryFileActions from './binary-file.actions';
+
+describe('BinaryFileEffects', () => {
+	let actions: Observable<Action>;
+	let effects: BinaryFileEffects;
+
+	const binaryFileRepository: Mock<BinaryFileRepository> = mock(BinaryFileRepository);
+
+	beforeEach(() => {
+		TestBed.configureTestingModule({
+			imports: [NxModule.forRoot()],
+			providers: [
+				BinaryFileEffects,
+				provideMockActions(() => actions),
+				provideMockStore(),
+				{
+					provide: BinaryFileRepository,
+					useValue: binaryFileRepository
+				},
+			],
+		});
+
+		effects = TestBed.inject(BinaryFileEffects);
+	});
+
+	describe('downloadPdf', () => {
+
+		const uri: ResourceUri = faker.internet.url();
+		const fileName: string = faker.random.alphaNumeric();
+		const fileData: Blob = new Blob();
+
+		const downloadAsPdfSuccess: TypedActionCreator = createAction('[Test Action] Download Success');
+		//const downloadAsPdfFailure: TypedActionCreatorWithProps<ApiErrorAction>;// = createAction('[BinaryFile/Test] Download Failure', props<ApiErrorAction>());
+
+		const downloadPdfAction = BinaryFileActions.downloadPdf({ successAction: downloadAsPdfSuccess, failureAction: null, fileName, uri });
+
+		it('should call repository', () => {
+			actions = hot('-a', { a: downloadPdfAction });
+
+			effects.downloadPdf$.subscribe(() => {
+				expect(binaryFileRepository.downloadPdf).toHaveBeenCalledWith(uri);
+			});
+		});
+
+		it('should return actions on success', () => {
+			binaryFileRepository.downloadPdf.mockReturnValue(of(fileData));
+
+			actions = hot('-a', { a: downloadPdfAction });
+
+			const expected = cold('-(bc)', {
+				b: BinaryFileActions.saveAsPdf({ fileName, fileData }),
+				c: downloadAsPdfSuccess()
+			});
+			expect(effects.downloadPdf$).toBeObservable(expected);
+		});
+
+		it('should return actions on failure', () => {
+
+		})
+	});
+
+	describe('saveAsPdf', () => {
+
+		const fileName: string = faker.random.alphaNumeric();
+		const fileData: Blob = new Blob();
+
+		it('should save file', () => {
+			effects.save = jest.fn();
+
+			actions = hot('a', { a: BinaryFileActions.saveAsPdf({ fileData, fileName }) });
+
+			effects.saveAsPdf$.subscribe(() => {
+				expect(effects.save).toHaveBeenCalledWith(fileData, fileName);
+			})
+		})
+	})
+});
diff --git a/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.effects.ts b/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5d0673cd46750ecc52cc70b595a42ef315e310fb
--- /dev/null
+++ b/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.effects.ts
@@ -0,0 +1,35 @@
+import { Injectable } from '@angular/core';
+import { Actions, createEffect, ofType } from '@ngrx/effects';
+import { mergeMap, switchMap, tap } from 'rxjs/operators';
+import { BinaryFileRepository } from '../binary-file.repository';
+
+import * as saveAs from 'file-saver';
+import * as BinaryFileActions from './binary-file.actions';
+import { DownloadBinaryFileAsPdfAction, SaveBinaryFileAsPdfAction } from './binary-file.actions';
+
+@Injectable()
+export class BinaryFileEffects {
+
+	constructor(private readonly actions$: Actions, private readonly binaryFileRepository: BinaryFileRepository) { }
+
+	downloadPdf$ = createEffect(() =>
+		this.actions$.pipe(
+			ofType(BinaryFileActions.downloadPdf),
+			switchMap((action: DownloadBinaryFileAsPdfAction) => this.binaryFileRepository.downloadPdf(action.uri).pipe(
+				mergeMap((fileData: Blob) => [BinaryFileActions.saveAsPdf({ fileData, fileName: action.fileName }), action.successAction()])
+				//catchError(error => of(action.failureAction(getApiErrorFromHttpErrorResponse(error))))
+			))
+		)
+	);
+
+	saveAsPdf$ = createEffect(() =>
+		this.actions$.pipe(
+			ofType(BinaryFileActions.saveAsPdf),
+			tap((action: SaveBinaryFileAsPdfAction) => this.save(action.fileData, action.fileName))
+		), { dispatch: false })
+
+
+	save(fileData: Blob, name: string): void {
+		saveAs(fileData, name);
+	}
+}
\ No newline at end of file
diff --git a/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.reducer.ts b/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.reducer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..780e0f16490e8c7ea469de48c1b347cb52b3b40d
--- /dev/null
+++ b/goofy-client/libs/binary-file-shared/src/lib/+state/binary-file.reducer.ts
@@ -0,0 +1,17 @@
+import { Action, createReducer } from '@ngrx/store';
+
+export const BINARY_FILE_FEATURE_KEY = 'BinaryFileState';
+
+export interface BinaryFileState { }
+
+export interface BinaryFilePartialState {
+	readonly [BINARY_FILE_FEATURE_KEY]: BinaryFileState;
+}
+
+export const initialBinaryFileState: BinaryFileState = {};
+
+const reducer = createReducer(initialBinaryFileState);
+
+export function binaryFileReducer(state: BinaryFileState, action: Action) {
+	return reducer(state, action);
+}
\ No newline at end of file
diff --git a/goofy-client/libs/binary-file-shared/src/lib/binary-file-shared.module.ts b/goofy-client/libs/binary-file-shared/src/lib/binary-file-shared.module.ts
index 524504acd5a8541590f7224ece64dd0dbfe46dec..4da60471e937dc30cb7e217667b88c69984e1e6e 100644
--- a/goofy-client/libs/binary-file-shared/src/lib/binary-file-shared.module.ts
+++ b/goofy-client/libs/binary-file-shared/src/lib/binary-file-shared.module.ts
@@ -1,7 +1,18 @@
 import { CommonModule } from '@angular/common';
 import { NgModule } from '@angular/core';
+import { EffectsModule } from '@ngrx/effects';
+import { StoreModule } from '@ngrx/store';
+import { BinaryFileEffects } from './+state/binary-file.effects';
+import * as fromBinaryFile from './+state/binary-file.reducer';
 
 @NgModule({
-	imports: [CommonModule],
+	imports: [
+		CommonModule,
+		StoreModule.forFeature(
+			fromBinaryFile.BINARY_FILE_FEATURE_KEY,
+			fromBinaryFile.binaryFileReducer
+		),
+		EffectsModule.forFeature([BinaryFileEffects]),
+	]
 })
 export class BinaryFileSharedModule { }
diff --git a/goofy-client/libs/binary-file-shared/src/lib/binary-file.repository.spec.ts b/goofy-client/libs/binary-file-shared/src/lib/binary-file.repository.spec.ts
index 6a145a53fc721d4e8aafcd07109daa9f84d40095..67944b877d0694b0c9f2fe8d917c489412d08f1a 100644
--- a/goofy-client/libs/binary-file-shared/src/lib/binary-file.repository.spec.ts
+++ b/goofy-client/libs/binary-file-shared/src/lib/binary-file.repository.spec.ts
@@ -7,7 +7,7 @@ import { cold, hot } from 'jest-marbles';
 import { DummyLinkRel } from 'libs/tech-shared/test/dummy';
 import { createDummyListResource, createDummyResource } from 'libs/tech-shared/test/resource';
 import { of } from 'rxjs';
-import { BinaryFileRepository, GetRequestOptions } from './binary-file.repository';
+import { BinaryFileRepository, ContentType, GetRequestOptions } from './binary-file.repository';
 
 describe('BinaryFileRepository', () => {
 	let repository: BinaryFileRepository;
@@ -96,14 +96,61 @@ describe('BinaryFileRepository', () => {
 
 		function getExpectedRequestOptions(): HttpHeaders {
 			let headers = new HttpHeaders();
-			headers = headers.set('Accept', ['application/*', 'images/*']);
+			headers = headers.set('Accept', [ContentType.APPLICATION_ALL, ContentType.IMAGES_ALL]);
+			return headers;
+		}
+	})
+
+	describe('downloadPdf', () => {
+
+		const blob = {};
+		const uri: ResourceUri = faker.internet.url();
+
+		beforeEach(() => {
+			httpClient.get.mockReturnValue(hot('a', { a: blob }));
+		})
+
+		it('should call httpClient', () => {
+			const requestOptions = {};
+			repository.buildPdfRequestOptions = jest.fn();
+			(<any>repository.buildPdfRequestOptions).mockReturnValue(requestOptions);
+
+			repository.downloadPdf(uri);
+
+			expect(httpClient.get).toHaveBeenCalledWith(uri, requestOptions);
+		})
+
+		it('should return value', () => {
+			const result = repository.downloadPdf(uri);
+
+			expect(result).toBeObservable(cold('b', { b: blob }));
+		})
+
+		describe('buildPdfRequestOptions', () => {
+
+			it('should return httpHeaders', () => {
+				const result: GetRequestOptions = repository.buildPdfRequestOptions();
+
+				expect(result.responseType).toEqual('blob');
+			})
+
+			it('should return responseType', () => {
+				const result: GetRequestOptions = repository.buildPdfRequestOptions();
+
+				expect(result.headers).toEqual(getExpectedRequestOptions());
+			})
+		})
+
+		function getExpectedRequestOptions(): HttpHeaders {
+			let headers = new HttpHeaders();
+			headers = headers.set('Accept', [ContentType.APPLICATION_PDF]);
 			return headers;
 		}
 	})
 
 	describe('get file', () => {
 
-		const uri: ResourceUri = getUrl(createDummyResource());
+		const uri: ResourceUri = faker.internet.url();
 
 		it('should call repository factory', () => {
 			repository.getFile(uri);
@@ -139,21 +186,4 @@ describe('BinaryFileRepository', () => {
 			expect(resourceWrapper.get).toHaveBeenCalledWith(DummyLinkRel.DUMMY);
 		})
 	})
-
-	describe('get file', () => {
-
-		const uri: ResourceUri = faker.internet.url();
-
-		it('should call repository factory', () => {
-			repository.getFile(uri);
-
-			expect(resourceFactory.fromId).toHaveBeenCalledWith(uri);
-		})
-
-		it('should call repository wrapper', () => {
-			repository.getFile(uri);
-
-			expect(resourceWrapper.get).toHaveBeenCalled();
-		})
-	})
 })
\ No newline at end of file
diff --git a/goofy-client/libs/binary-file-shared/src/lib/binary-file.repository.ts b/goofy-client/libs/binary-file-shared/src/lib/binary-file.repository.ts
index ebe0ae6c610676eab25797728efe670ebe064cf5..5ef153ffac5efcd06493c8c892b04d587a795ff3 100644
--- a/goofy-client/libs/binary-file-shared/src/lib/binary-file.repository.ts
+++ b/goofy-client/libs/binary-file-shared/src/lib/binary-file.repository.ts
@@ -14,16 +14,32 @@ export class BinaryFileRepository {
 
 		formData.append('file', file, file.name);
 
-		return this.httpClient.post(getUrl(resource, linkRel), formData, { observe: 'response' })
+		return this.httpClient.post(getUrl(resource, linkRel), formData, { observe: 'response' });
 	}
 
 	public download(fileResource: Resource, linkRel: string): Observable<Blob> {
-		return this.httpClient.get<Blob>(getUrl(fileResource, linkRel), this.buildRequestOptions());
+		return this.doDownload(getUrl(fileResource, linkRel), this.buildRequestOptions());
 	}
 
 	buildRequestOptions(): GetRequestOptions {
+		return this.buildBaseRequestOptions([ContentType.APPLICATION_ALL, ContentType.IMAGES_ALL]);
+	}
+
+	public downloadPdf(uri: ResourceUri): Observable<Blob> {
+		return this.doDownload(uri, this.buildPdfRequestOptions());
+	}
+
+	private doDownload(uri: ResourceUri, requestOptions: GetRequestOptions): Observable<Blob> {
+		return this.httpClient.get<Blob>(uri, requestOptions);
+	}
+
+	buildPdfRequestOptions(): GetRequestOptions {
+		return this.buildBaseRequestOptions([ContentType.APPLICATION_PDF]);
+	}
+
+	buildBaseRequestOptions(contentTypes: ContentType[]): GetRequestOptions {
 		let headers = new HttpHeaders();
-		headers = headers.set('Accept', ['application/*', 'images/*']);
+		headers = headers.set('Accept', contentTypes);
 		return { headers, responseType: 'blob' as 'json' };
 	}
 
@@ -37,6 +53,12 @@ export class BinaryFileRepository {
 }
 
 export interface GetRequestOptions {
-	headers?: HttpHeaders | { [header: string]: string | string[] };
-	responseType?: 'json';
+	headers: HttpHeaders | { [header: string]: string | string[] };
+	responseType: 'json';
+}
+
+export enum ContentType {
+	APPLICATION_PDF = 'application/pdf',
+	IMAGES_ALL = 'images/*',
+	APPLICATION_ALL = 'application/*'
 }
\ No newline at end of file