diff --git a/proto/references/references.proto b/proto/references/references.proto
index e8ef011f881d9f77f13da7f29ee63a07c3d26a87..d84be735ba0eea3e4abbf979e3fc8976d0580e97 100644
--- a/proto/references/references.proto
+++ b/proto/references/references.proto
@@ -1,16 +1,33 @@
 syntax = "proto3";
 
 import "items/items.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/duration.proto";
 
 option go_package = "git.perx.ru/perxis/perxis-go/proto/references;references";
 
 package content.references;
 
 
+// Reference - ссылка на запись
 message Reference {
-  string id = 1;
-  string collection_id = 2;
-  bool disabled = 3;
+  string id = 1; // ID записи
+  string collection_id = 2; // ID коллекции
+  bool disabled = 3; // Если true, то ссылка игнорируется
+  string space_id = 4; // ID пространства, в котором находится запись (опционально, если не указано, то текущее пространство)
+  string env_id = 5; // ID окружения, в котором находится запись (опционально, если не указано, то текущее окружение)
+  items.Item item = 6; // Запись, на которую ссылается ссылка
+}
+
+// Relation - связь между двумя объектами указанными в ссылках
+message Relation {
+  Reference to = 1; // Ссылка на объект, на который указывает связь
+  Reference from = 2; // Ссылка на объект, от которого исходит связь
+  string type = 3; // РўРёРї СЃРІСЏР·Рё
+  // int32 weight = 4; // Вес связи
+  // uint32 epoch = 5; // Используется в процессе перестроения связей
+  // bool bidirectional = 6; // Если true, то связь двунаправленная
 }
 
 message GetRequest {
@@ -19,13 +36,111 @@ message GetRequest {
   repeated Reference references = 3;
 }
 
+
+// GetRespone принимает список ссылок на записи и возвращает два списка:
+// список найденных записей и не найденных ссылок
 message GetResponse {
   repeated items.Item items = 1;
   repeated Reference notfound = 2;
 }
 
-// References принимает список ссылок на записи и возвращает два списка:
-// список найденных записей и не найденных ссылок
+// SetRelationRequest принимает две ссылки и тип связи
+message SetRelationsRequest {
+  repeated Relation relation = 1;
+  bool skip_verify = 2; // Если true, то не проверять существование записей
+}
+
+// SetRelationsResponse возвращает количество установленных связей и список не установленных связей
+message SetRelationsResponse {
+  int32 count = 1; // Количество установленных связей
+  repeated Relation notfound = 2; // Список не установленных связей
+}
+
+// RelationsRequest принимает параметры для поиска связей
+message GetRelationsRequest {
+  Reference to = 1; // Если указано, то возвращать только связи на указанную запись
+  Reference from = 2; // Если указано, то возвращать только связи от указанной записи
+  repeated string type = 3; // Если указано, то возвращать только связи с указанными типами
+  bool deref = 6; // Если true, то возвращать записи, на которые указывают ссылки
+  bool total = 7; // Если true, то возвращать количество связей
+  int32 limit = 10; // Если указано, то возвращать только указанное количество записей (по умолчанию 10)
+  int32 offset = 11; // Если указано, то возвращать записи начиная с указанного смещения
+}
+
+// GetRelationsResponse возвращает список связей
+message GetRelationsResponse {
+  repeated Relation relations = 1; // Список связей
+  int32 count = 2; // Возвращается количество связей
+  int32 limit = 10; // Какое количество записей было запрошено
+  int32 offset = 11; // Какое смещение было запрошено
+  int32 total = 12; // Если запрошено, то возвращается количество связей
+}
+
+// RemoveRelationRequest принимает две ссылки и тип связи
+message RemoveRelationsRequest {
+  Reference to = 1; // Если указано, то удаляются только связи на указанную запись
+  Reference from = 2; // Если указано, то удаляются только связи от указанной записи
+  repeated string type = 3; // Если указано, то удаляются только связи с указанными типами
+}
+
+// RemoveRelationsResponse возвращает количество удаленных связей
+message RemoveRelationsResponse {
+  int32 count = 1; // Количество удаленных связей
+}
+
+// RebuildRelationsRequest принимает параметры для перестроения связей
+message RebuildRelationsRequest {
+  string space_id = 1; // Если указано, то перестраиваются только связи в указанном пространстве
+  string env_id = 2; // Если указано, то перестраиваются только связи в указанном окружении
+  repeated string collection_ids = 3; // Если указано, то перестраиваются только связи в указанных коллекциях
+}
+
+// RebuildRelationsResponse возвращает токен, по которому можно получить статус перестроения связей
+// токен действует 1 час
+message RebuildRelationsResponse {
+  string token = 1; // Токен, по которому можно получить статус перестроения связей
+}
+
+// RebuildRelationsStatusRequest принимает токен, по которому можно получить статус перестроения связей
+message RebuildRelationsStatusRequest {
+  string token = 1; // Токен, по которому можно получить статус перестроения связей
+}
+
+// RebuildRelationsStatusResponse возвращает статус перестроения связей
+message RebuildRelationsStatusResponse {
+  bool done = 1; // Если true, то перестроение завершено
+  int32 relations_count = 2; // Количество связей, которые уже перестроены
+  int32 items_count = 3; // Количество записей, которые уже обработаны
+  google.protobuf.Timestamp started_at = 4; // Время начала перестроения
+  google.protobuf.Timestamp finished_at = 5; // Время окончания перестроения
+  google.protobuf.Duration duration = 6; // Продолжительность перестроения
+}
+
+// CancelRebuildRelationsRequest принимает токен, по которому можно отменить перестроение связей
+message CancelRebuildRelationsRequest {
+  string token = 1; // Токен, по которому можно отменить перестроение связей
+}
+
 service References  {
+  // Возвращает список записей по ссылкам
   rpc Get(GetRequest) returns(GetResponse) {}
+
+  // Устанавливает связь между двумя записями
+  rpc SetRelations(SetRelationsRequest) returns(SetRelationsResponse) {}
+
+  // Возвращает список связей
+  rpc GetRelations(GetRelationsRequest) returns(GetRelationsResponse) {}
+
+  // Удаляет связи
+  rpc RemoveRelations(RemoveRelationsRequest) returns(RemoveRelationsResponse) {}
+
+  // Перестраивает связи
+  // Может быть долгим, поэтому выполняется асинхронно, возвращает пустой ответ
+  rpc RebuildRelations(RebuildRelationsRequest) returns(RebuildRelationsResponse) {}
+
+  // Возвращает статус перестроения связей
+  rpc RebuildRelationsStatus(RebuildRelationsStatusRequest) returns(RebuildRelationsResponse) {}
+
+  // Отменяет перестроение связей
+  rpc CancelRebuildRelations(CancelRebuildRelationsRequest) returns(google.protobuf.Empty) {}
 }