diff --git a/pkg/invitations/encoder/grpc.go b/pkg/invitations/encoder/grpc.go
index a4488c09ab25dc5663b48b28ab57d25540779aa0..d74cc10d64961da4f965763fb7030bbc19e1923a 100644
--- a/pkg/invitations/encoder/grpc.go
+++ b/pkg/invitations/encoder/grpc.go
@@ -4,6 +4,7 @@ import (
 	"git.perx.ru/perxis/perxis-go/pkg/invitations"
 	"git.perx.ru/perxis/perxis-go/pkg/options"
 	pb "git.perx.ru/perxis/perxis-go/proto/invitations"
+	timestamp "google.golang.org/protobuf/types/known/timestamppb"
 )
 
 type Encoder struct {
@@ -11,84 +12,188 @@ type Encoder struct {
 
 var _ invitations.ProtoEncoder = &Encoder{}
 
-func (d Encoder) EncodeAcceptRequest(invitationId string, userId string) *pb.AcceptRequest {
+func (e *Encoder) EncodeAcceptRequest(invitationId string, userId string) *pb.AcceptRequest {
 	return &pb.AcceptRequest{
 		InvitationId: invitationId,
 		UserId:       userId,
 	}
 }
 
-func (d Encoder) DecodeAcceptRequest(request *pb.AcceptRequest) (invitationId string, userId string) {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) DecodeAcceptRequest(request *pb.AcceptRequest) (invitationId string, userId string) {
+	if request == nil {
+		return
+	}
+	return request.InvitationId, request.UserId
 }
 
-func (d Encoder) EncodeCreateRequest(invitation *invitations.Invitation) *pb.CreateRequest {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) EncodeCreateRequest(invitation *invitations.Invitation) *pb.CreateRequest {
+	return &pb.CreateRequest{
+		Invitation: InvitationToProto(invitation),
+	}
 }
 
-func (d Encoder) DecodeCreateRequest(request *pb.CreateRequest) (invitation *invitations.Invitation) {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) DecodeCreateRequest(request *pb.CreateRequest) (invitation *invitations.Invitation) {
+	if request == nil {
+		return
+	}
+	return InvitationFromProto(request.Invitation)
 }
 
-func (d Encoder) EncodeCreateResponse(response *pb.CreateResponse) (created *invitations.Invitation) {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) EncodeCreateResponse(response *pb.CreateResponse) (created *invitations.Invitation) {
+	if response == nil {
+		return
+	}
+	return InvitationFromProto(response.Invitation)
 }
 
-func (d Encoder) DecodeCreateResponse(created *invitations.Invitation) *pb.CreateResponse {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) DecodeCreateResponse(created *invitations.Invitation) *pb.CreateResponse {
+	return &pb.CreateResponse{
+		Invitation: InvitationToProto(created),
+	}
 }
 
-func (d Encoder) EncodeDeleteRequest(invitationId string) *pb.DeleteRequest {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) EncodeDeleteRequest(invitationId string) *pb.DeleteRequest {
+	return &pb.DeleteRequest{
+		InvitationId: invitationId,
+	}
 }
 
-func (d Encoder) DecodeDeleteRequest(request *pb.DeleteRequest) (invitationId string) {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) DecodeDeleteRequest(request *pb.DeleteRequest) (invitationId string) {
+	return request.InvitationId
 }
 
-func (d Encoder) EncodeFindRequest(filter *invitations.Filter, opts *options.FindOptions) *pb.FindRequest {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) EncodeFindRequest(filter *invitations.Filter, opts *options.FindOptions) *pb.FindRequest {
+	request := &pb.FindRequest{}
+
+	if request.Filter != nil {
+		filter = &invitations.Filter{
+			ID:      request.Filter.Id,
+			Email:   request.Filter.Email,
+			OrgID:   request.Filter.OrgId,
+			SpaceID: request.Filter.SpaceId,
+			OwnerID: request.Filter.OwnerId,
+			Role:    request.Filter.Role,
+		}
+	}
+
+	if request.Options != nil {
+		opts = options.FindOptionsFromPB(request.Options)
+	}
+
+	return request
 }
 
-func (d Encoder) DecodeFindRequest(request *pb.FindRequest) (filter *invitations.Filter, opts *options.FindOptions) {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) DecodeFindRequest(request *pb.FindRequest) (filter *invitations.Filter, opts *options.FindOptions) {
+	if request == nil {
+		return
+	}
+
+	if request.Filter != nil {
+		filter = &invitations.Filter{
+			ID:      request.Filter.Id,
+			Email:   request.Filter.Email,
+			OrgID:   request.Filter.OrgId,
+			SpaceID: request.Filter.SpaceId,
+			OwnerID: request.Filter.OwnerId,
+			Role:    request.Filter.Role,
+		}
+	}
+
+	if request.Options != nil {
+		opts = options.FindOptionsFromPB(request.Options)
+	}
+	return
 }
 
-func (d Encoder) EncodeFindResponse(response *pb.FindResponse) (invitations []*invitations.Invitation, total int) {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) EncodeFindResponse(response *pb.FindResponse) (invitations []*invitations.Invitation, total int) {
+	if response == nil {
+		return
+	}
+
+	total = int(response.Total)
+	for _, pi := range response.Invitations {
+		invitations = append(invitations, InvitationFromProto(pi))
+	}
+	return
 }
 
-func (d Encoder) DecodeFindResponse(invitations []*invitations.Invitation, total int) *pb.FindResponse {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) DecodeFindResponse(invitations []*invitations.Invitation, total int) *pb.FindResponse {
+	protoInvitations := make([]*pb.Invitation, 0, len(invitations))
+	for _, i := range invitations {
+		protoInvitations = append(protoInvitations, InvitationToProto(i))
+	}
+	return &pb.FindResponse{
+		Invitations: protoInvitations,
+		Total:       int64(total),
+	}
+}
+
+func (e *Encoder) EncodeGetRequest(invitationId string) *pb.GetRequest {
+	return &pb.GetRequest{
+		InvitationId: invitationId,
+	}
 }
 
-func (d Encoder) EncodeGetRequest(invitationId string) *pb.GetRequest {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) DecodeGetRequest(request *pb.GetRequest) (invitationId string) {
+	if request == nil {
+		return
+	}
+	return request.InvitationId
 }
 
-func (d Encoder) DecodeGetRequest(request *pb.GetRequest) (invitationId string) {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) EncodeGetResponse(response *pb.GetResponse) (invitation *invitations.Invitation) {
+	if response == nil {
+		return
+	}
+	return InvitationFromProto(response.Invitation)
 }
 
-func (d Encoder) EncodeGetResponse(response *pb.GetResponse) (invitation *invitations.Invitation) {
-	// TODO implement me
-	panic("implement me")
+func (e *Encoder) DecodeGetResponse(invitation *invitations.Invitation) *pb.GetResponse {
+	return &pb.GetResponse{
+		Invitation: InvitationToProto(invitation),
+	}
 }
 
-func (d Encoder) DecodeGetResponse(invitation *invitations.Invitation) *pb.GetResponse {
-	// TODO implement me
-	panic("implement me")
+func InvitationToProto(invitation *invitations.Invitation) *pb.Invitation {
+	if invitation == nil {
+		return nil
+	}
+	pi := &pb.Invitation{
+		Id:      invitation.ID,
+		Email:   invitation.Email,
+		OrgId:   invitation.OrgID,
+		SpaceId: invitation.SpaceID,
+		OwnerId: invitation.OwnerID,
+		Role:    invitation.Role,
+	}
+	if invitation.CreatedAt != nil && !invitation.CreatedAt.IsZero() {
+		pi.CreatedAt = timestamp.New(*invitation.CreatedAt)
+	}
+	if invitation.ValidUntil != nil && !invitation.ValidUntil.IsZero() {
+		pi.ValidUntil = timestamp.New(*invitation.ValidUntil)
+	}
+	return pi
+}
+
+func InvitationFromProto(protoInvitation *pb.Invitation) *invitations.Invitation {
+	if protoInvitation == nil {
+		return nil
+	}
+	i := &invitations.Invitation{
+		ID:      protoInvitation.Id,
+		Email:   protoInvitation.Email,
+		OrgID:   protoInvitation.OrgId,
+		SpaceID: protoInvitation.SpaceId,
+		OwnerID: protoInvitation.OwnerId,
+		Role:    protoInvitation.Role,
+	}
+	if protoInvitation.CreatedAt != nil {
+		t := protoInvitation.CreatedAt.AsTime()
+		i.CreatedAt = &t
+	}
+	if protoInvitation.ValidUntil != nil {
+		t := protoInvitation.ValidUntil.AsTime()
+		i.ValidUntil = &t
+	}
+	return i
 }