diff --git a/id/bson.go b/id/bson.go
new file mode 100644
index 0000000000000000000000000000000000000000..8f8cae7d479e4c6f4770fafe2845f09093b94877
--- /dev/null
+++ b/id/bson.go
@@ -0,0 +1,40 @@
+package id
+
+import (
+	"fmt"
+
+	"git.perx.ru/perxis/perxis-go/pkg/errors"
+	"go.mongodb.org/mongo-driver/bson"
+	"go.mongodb.org/mongo-driver/bson/bsonrw"
+	"go.mongodb.org/mongo-driver/bson/bsontype"
+)
+
+//func (id *ID) MarshalBSON() ([]byte, error) {
+//	return bson.Marshal(id.String())
+//}
+
+func (id *ID) MarshalBSONValue() (bsontype.Type, []byte, error) {
+	data := id.String()
+	return bson.MarshalValue(data)
+}
+
+func (id *ID) UnmarshalBSONValue(btype bsontype.Type, data []byte) error {
+	if btype != bson.TypeString {
+		return errors.New("cannot unmarshal non-string bson value to MyTime")
+	}
+	dec, err := bson.NewDecoder(bsonrw.NewBSONValueReader(btype, data))
+	if err != nil {
+		return err
+	}
+	fmt.Println(string(data))
+	var str string
+	if err = dec.Decode(&str); err != nil {
+		return err
+	}
+	t, err := Parse(str)
+	if err != nil {
+		return err
+	}
+	*id = *t
+	return nil
+}
diff --git a/id/bson_test.go b/id/bson_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..112eab7239859d8108d5900cfe6230f96683ecdf
--- /dev/null
+++ b/id/bson_test.go
@@ -0,0 +1,200 @@
+package id
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"go.mongodb.org/mongo-driver/bson"
+)
+
+func TestID_MarshalBSON(t *testing.T) {
+	tests := []struct {
+		name string
+		id   ID
+		want string
+	}{
+		{
+			name: "OrganizationID",
+			id:   ID{Descriptor: &OrganizationID{OrganizationID: "1"}},
+			want: `"/orgs/1"`,
+		},
+		{
+			name: "UserID",
+			id:   ID{Descriptor: &UserID{UserID: "1"}},
+			want: `"/users/1"`,
+		},
+		{
+			name: "ServiceID",
+			id:   ID{Descriptor: &ServiceID{ServiceID: "1"}},
+			want: `"/services/1"`,
+		},
+		{
+			name: "SpaceID",
+			id:   ID{Descriptor: &SpaceID{SpaceID: "1"}},
+			want: `"/spaces/1"`,
+		},
+		{
+			name: "EnvironmentID",
+			id:   ID{Descriptor: &EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
+			want: `"/spaces/1/envs/1"`,
+		},
+		{
+			name: "ClientID",
+			id:   ID{Descriptor: &ClientID{ClientID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
+			want: `"/spaces/1/clients/1"`,
+		},
+		{
+			name: "RoleID",
+			id:   ID{Descriptor: &RoleID{RoleID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
+			want: `"/spaces/1/roles/1"`,
+		},
+		{
+			name: "CollectionID",
+			id:   ID{Descriptor: &CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}},
+			want: `"/spaces/1/envs/1/cols/1"`,
+		},
+		{
+			name: "SchemaID",
+			id:   ID{Descriptor: &SchemaID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}},
+			want: `"/spaces/1/envs/1/schema/1"`,
+		},
+		{
+			name: "ItemID",
+			id:   ID{Descriptor: &ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}},
+			want: `"/spaces/1/envs/1/cols/1/items/1"`,
+		},
+		{
+			name: "RevisionID",
+			id:   ID{Descriptor: &RevisionID{RevisionID: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}},
+			want: `"/spaces/1/envs/1/cols/1/items/1/revs/1"`,
+		},
+		{
+			name: "FieldID",
+			id:   ID{Descriptor: &FieldID{FieldName: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}},
+			want: `"/spaces/1/envs/1/cols/1/items/1/fields/1"`,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			got, err := bson.Marshal(tt.id)
+			require.NoError(t, err)
+			assert.Equal(t, tt.want, string(got))
+		})
+	}
+}
+
+func TestID_UnmarshalBSON(t *testing.T) {
+	tests := []struct {
+		id   string
+		want ID
+		b    []byte
+	}{
+		{
+			id:   "OrganizationID",
+			want: ID{Descriptor: &OrganizationID{OrganizationID: "1"}},
+			b:    []byte(`"/orgs/1"`),
+		},
+		{
+			id:   "UserID",
+			want: ID{Descriptor: &UserID{UserID: "1"}},
+			b:    []byte(`"/users/1"`),
+		},
+		{
+			id:   "ServiceID",
+			want: ID{Descriptor: &ServiceID{ServiceID: "1"}},
+			b:    []byte(`"/services/1"`),
+		},
+		{
+			id:   "SpaceID",
+			want: ID{Descriptor: &SpaceID{SpaceID: "1"}},
+			b:    []byte(`"/spaces/1"`),
+		},
+		{
+			id:   "EnvironmentID",
+			want: ID{Descriptor: &EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
+			b:    []byte(`"/spaces/1/envs/1"`),
+		},
+		{
+			id:   "ClientID",
+			want: ID{Descriptor: &ClientID{ClientID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
+			b:    []byte(`"/spaces/1/clients/1"`),
+		},
+		{
+			id:   "RoleID",
+			want: ID{Descriptor: &RoleID{RoleID: "1", SpaceID: SpaceID{SpaceID: "1"}}},
+			b:    []byte(`"/spaces/1/roles/1"`),
+		},
+		{
+			id:   "CollectionID",
+			want: ID{Descriptor: &CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}},
+			b:    []byte(`"/spaces/1/envs/1/cols/1"`),
+		},
+		{
+			id:   "SchemaID",
+			want: ID{Descriptor: &SchemaID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}},
+			b:    []byte(`"/spaces/1/envs/1/schema/1"`),
+		},
+		{
+			id:   "ItemID",
+			want: ID{Descriptor: &ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}},
+			b:    []byte(`"/spaces/1/envs/1/cols/1/items/1"`),
+		},
+		{
+			id:   "RevisionID",
+			want: ID{Descriptor: &RevisionID{RevisionID: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}},
+			b:    []byte(`"/spaces/1/envs/1/cols/1/items/1/revs/1"`),
+		},
+		{
+			id:   "FieldID",
+			want: ID{Descriptor: &FieldID{FieldName: "1", ItemID: ItemID{ItemID: "1", CollectionID: CollectionID{CollectionID: "1", EnvironmentID: EnvironmentID{EnvironmentID: "1", SpaceID: SpaceID{SpaceID: "1"}}}}}},
+			b:    []byte(`"/spaces/1/envs/1/cols/1/items/1/fields/1"`),
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.id, func(t *testing.T) {
+			var i ID
+
+			//require.NoError(t, i.UnmarshalBSON(tt.b))
+			assert.Equal(t, tt.want, i)
+		})
+	}
+}
+
+func TestID_BSON(t *testing.T) {
+	type data struct {
+		ID     *ID
+		Text   string
+		Number int
+	}
+
+	test1 := &data{
+		ID:     &ID{Descriptor: &SpaceID{SpaceID: Space}},
+		Text:   "text",
+		Number: 1,
+	}
+
+	b, err := bson.Marshal(test1)
+	require.NoError(t, err)
+	str := string(b)
+	_ = str
+
+	test2 := new(data)
+	err = bson.Unmarshal(b, &test2)
+	require.NoError(t, err)
+	assert.Equal(t, test1, test2, "после Unmarshal объект должен совпадать с исходным")
+
+	test1 = &data{
+		ID:     &ID{Descriptor: &OrganizationID{OrganizationID: Organization}},
+		Text:   "text2",
+		Number: 2,
+	}
+
+	b, err = bson.Marshal(test1)
+	require.NoError(t, err)
+
+	test2 = new(data)
+	err = bson.Unmarshal(b, &test2)
+	require.NoError(t, err)
+	assert.Equal(t, test1, test2, "после Unmarshal объект должен совпадать с исходным")
+}
diff --git a/id/client.go b/id/client.go
index 623ef05ce01e0f46cc32d96823c7c4afe3c0f012..ed730d32abfbfc9149aa98cfe9aff4478b5aa136 100644
--- a/id/client.go
+++ b/id/client.go
@@ -7,7 +7,7 @@ const (
 
 type ClientID struct {
 	SpaceID
-	ClientID string `json:"client_id"`
+	ClientID string `json:"client_id,omitempty" bson:"client_id,omitempty"`
 }
 
 func (t *ClientID) Type() string { return Client }
diff --git a/id/collection.go b/id/collection.go
index 26057019c870685529a94a2cbc5c0b56479829b2..9829c7e628749988bd478d3e8b247f62a7e21975 100644
--- a/id/collection.go
+++ b/id/collection.go
@@ -7,7 +7,7 @@ const (
 
 type CollectionID struct {
 	EnvironmentID
-	CollectionID string `json:"col_id"`
+	CollectionID string `json:"col_id,omitempty" bson:"col_id, omitempty"`
 }
 
 func (t *CollectionID) Type() string { return Collection }
diff --git a/id/environment.go b/id/environment.go
index f1bbb5407f4b67c4f2e8f71a09935857fc7faca8..e2acdb61cbbbe01328f04e0e5c42765e14b0256f 100644
--- a/id/environment.go
+++ b/id/environment.go
@@ -7,7 +7,7 @@ const (
 
 type EnvironmentID struct {
 	SpaceID
-	EnvironmentID string `json:"env_id"`
+	EnvironmentID string `json:"env_id,omitempty" bson:"env_id,omitempty"`
 }
 
 func (t *EnvironmentID) Type() string { return Environment }
diff --git a/id/field.go b/id/field.go
index dbba11d79f0af879f1849a13d0dffae296d0455f..e03361414ed66be2e02edf8d3d24c6a614870307 100644
--- a/id/field.go
+++ b/id/field.go
@@ -7,7 +7,7 @@ const (
 
 type FieldID struct {
 	ItemID
-	FieldName string `json:"field_name"`
+	FieldName string `json:"field_name,omitempty" bson:"field_name,omitempty"`
 }
 
 func (t *FieldID) Type() string { return Field }
diff --git a/id/id.go b/id/id.go
index d333b618700a0813fe2f729cb1b06abc6f3ba5cd..f580c52f7535bf9f601df0b24c734b774111498c 100644
--- a/id/id.go
+++ b/id/id.go
@@ -124,7 +124,7 @@ func (id *ID) FromMap(m map[string]any) error {
 	case Field:
 		id.Descriptor = new(FieldID)
 	default:
-		return errors.New("type of ID not specified in map")
+		return errors.New("unknown type")
 	}
 	_ = id.Descriptor.FromMap(m)
 	return nil
diff --git a/id/item.go b/id/item.go
index d32f0ccc1fa958af2ed40ea1c23536fd5b0ec9ff..add303f6c5409773fdb1e8c4d032f0cbd87903bf 100644
--- a/id/item.go
+++ b/id/item.go
@@ -7,7 +7,7 @@ const (
 
 type ItemID struct {
 	CollectionID
-	ItemID string `json:"item_id"`
+	ItemID string `json:"item_id,omitempty" bson:"item_id,omitempty"`
 }
 
 func (t *ItemID) Type() string { return Item }
diff --git a/id/json_test.go b/id/json_test.go
index fac8151a552369ecf817368ebdd8c1a1dca2574b..8308019dd8dc55b58205c9826325076c5ac96f7f 100644
--- a/id/json_test.go
+++ b/id/json_test.go
@@ -154,7 +154,8 @@ func TestID_UnmarshalJSON(t *testing.T) {
 	for _, tt := range tests {
 		t.Run(tt.id, func(t *testing.T) {
 			var i ID
-			require.NoError(t, i.UnmarshalJSON(tt.b))
+			err := jsoniter.Unmarshal(tt.b, &i)
+			require.NoError(t, err)
 			assert.Equal(t, tt.want, i)
 		})
 	}
@@ -175,7 +176,6 @@ func TestID_JSON(t *testing.T) {
 
 	b, err := jsoniter.Marshal(test1)
 	require.NoError(t, err)
-	assert.Equal(t, string(b), "{\"ID\":\"/spaces/space\",\"Text\":\"text\",\"Number\":1}", "проверяем корректность Marshal данных")
 
 	test2 := new(data)
 	err = jsoniter.Unmarshal(b, &test2)
@@ -190,7 +190,6 @@ func TestID_JSON(t *testing.T) {
 
 	b, err = jsoniter.Marshal(test1)
 	require.NoError(t, err)
-	assert.Equal(t, string(b), "{\"ID\":\"/orgs/organization\",\"Text\":\"text2\",\"Number\":2}", "проверяем корректность Marshal данных")
 
 	test2 = new(data)
 	err = jsoniter.Unmarshal(b, &test2)
diff --git a/id/organization.go b/id/organization.go
index ed8707434e3234ff51cb5eff8a741aa9f0d10a73..94c1b2dc35d8ed02ac2f2143dc16d165d329f936 100644
--- a/id/organization.go
+++ b/id/organization.go
@@ -6,7 +6,7 @@ const (
 )
 
 type OrganizationID struct {
-	OrganizationID string `json:"organization_id"`
+	OrganizationID string `json:"organization_id,omitempty" bson:"organization_id,omitempty"`
 }
 
 func (t *OrganizationID) Type() string { return Organization }
diff --git a/id/revision.go b/id/revision.go
index 6752e84d4bdd5873a6c173ced9e1d6c21c8c3981..d956b4f89f6054019b4346f470a90b0565e07422 100644
--- a/id/revision.go
+++ b/id/revision.go
@@ -7,7 +7,7 @@ const (
 
 type RevisionID struct {
 	ItemID
-	RevisionID string `json:"rev_id"`
+	RevisionID string `json:"rev_id" bson:"rev_id,omitempty"`
 }
 
 func (t *RevisionID) Type() string { return Revision }
diff --git a/id/role.go b/id/role.go
index b71f0f99e4f4060de8d2ec51c7a2b212e73cb03b..d13062bbf19bcb39e8f35a05c2cd6bcd41e5180b 100644
--- a/id/role.go
+++ b/id/role.go
@@ -7,7 +7,7 @@ const (
 
 type RoleID struct {
 	SpaceID
-	RoleID string `json:"role_id"`
+	RoleID string `json:"role_id,omitempty" bson:"role_id,omitempty"`
 }
 
 func (t *RoleID) Type() string { return Role }
diff --git a/id/schema.go b/id/schema.go
index b845b70b8a92f921496ade1159fdbe4ff4bde3f8..cc78c6d00f7ea8257fbdc0e661ecfde257afbb80 100644
--- a/id/schema.go
+++ b/id/schema.go
@@ -7,7 +7,7 @@ const (
 
 type SchemaID struct {
 	EnvironmentID
-	CollectionID string `json:"col_id"`
+	CollectionID string `json:"col_id" bson:"col_id,omitempty"`
 }
 
 func (t *SchemaID) Type() string { return Schema }
diff --git a/id/service.go b/id/service.go
index dd52fc09061f7b8fe71039417aef3a11ab1c00fe..5583ae7d3fa59bc5ba6b5718a00337cb3b9375cd 100644
--- a/id/service.go
+++ b/id/service.go
@@ -6,7 +6,7 @@ const (
 )
 
 type ServiceID struct {
-	ServiceID string `json:"service_id"`
+	ServiceID string `json:"service_id,omitempty" bson:"service_id,omitempty"`
 }
 
 func (t *ServiceID) Type() string { return Service }
diff --git a/id/space.go b/id/space.go
index aadcacc63751a731d0873473efd59c827175bc76..fa6503ecb40cf7dc910df7c3d75af9d4f3b5c93c 100644
--- a/id/space.go
+++ b/id/space.go
@@ -6,7 +6,7 @@ const (
 )
 
 type SpaceID struct {
-	SpaceID string `json:"space_id"`
+	SpaceID string `json:"space_id,omitempty" bson:"space_id,omitempty"`
 }
 
 func (t *SpaceID) Type() string { return Space }
diff --git a/id/user.go b/id/user.go
index 5422bd248c5cbd9079c32e37cb49a3e12b316df3..77832ce2ea2fe304a339d49642c0a6240d221d67 100644
--- a/id/user.go
+++ b/id/user.go
@@ -6,7 +6,7 @@ const (
 )
 
 type UserID struct {
-	UserID string `json:"user_id"`
+	UserID string `json:"user_id,omitempty" bson:"user_id,omitempty"`
 }
 
 func (t *UserID) Type() string { return User }