diff --git a/build-requirements.txt b/build-requirements.txt
index 0d90b1c10ad83d29f3d338eea8f9ed808ac07a0b..75d49c54821f25c01a78441ffc9d93fb26c72958 100644
--- a/build-requirements.txt
+++ b/build-requirements.txt
@@ -1,33 +1,33 @@
 appdirs==1.4.4
-build==0.4.0
-certifi==2020.12.5
+build==0.6.1
+certifi==2021.5.30
 chardet==4.0.0
 check-manifest==0.46
 devpi-client==5.2.2
 devpi-common==3.6.0
-distlib==0.3.1
+distlib==0.3.2
 filelock==3.0.12
 flake8==3.9.2
-grpcio==1.38.0
-grpcio-tools==1.38.0
-idna==2.10
-importlib-metadata==4.0.1
+grpcio==1.39.0
+grpcio-tools==1.39.0
+idna==3.2
+importlib-metadata==4.8.1
 lazy==1.4
 mccabe==0.6.1
-packaging==20.9
-pep517==0.9.1
-pkginfo==1.7.0
+packaging==21.0
+pep517==0.11.0
+pkginfo==1.7.1
 pluggy==0.13.1
-protobuf==3.17.1
+protobuf==3.17.3
 py==1.10.0
 pycodestyle==2.7.0
 pyflakes==2.3.1
 pyparsing==2.4.7
-requests==2.25.1
-six==1.15.0
+requests==2.26.0
+six==1.16.0
 toml==0.10.2
-tox==3.23.0
-typing-extensions==3.7.4.3
-urllib3==1.26.3
-virtualenv==20.4.2
-zipp==3.4.1
+tox==3.24.3
+typing-extensions==3.10.0.2
+urllib3==1.26.6
+virtualenv==20.7.2
+zipp==3.5.0
diff --git a/perxis/collections/collections_pb2.py b/perxis/collections/collections_pb2.py
index 649f2f00a762258c5322ffaf57df6425c6019846..cae262db736bb46caea85151174b3adef0b5ce10 100644
--- a/perxis/collections/collections_pb2.py
+++ b/perxis/collections/collections_pb2.py
@@ -12,6 +12,7 @@ _sym_db = _symbol_database.Default()
 
 
 from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
+from perxis.common import common_pb2 as perxis_dot_common_dot_common__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
@@ -20,13 +21,118 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z8github.com/perxteam/perxis/proto/collections;collections',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n$perxis/collections/collections.proto\x12\x13\x63ontent.collections\x1a\x1bgoogle/protobuf/empty.proto\"\x98\x01\n\nCollection\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x13\n\x06single\x18\x05 \x01(\x08H\x00\x88\x01\x01\x12\x13\n\x06system\x18\x06 \x01(\x08H\x01\x88\x01\x01\x12\x0e\n\x06schema\x18\x07 \x01(\tB\t\n\x07_singleB\t\n\x07_system\"D\n\rCreateRequest\x12\x33\n\ncollection\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"B\n\x0e\x43reateResponse\x12\x30\n\x07\x63reated\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"E\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\"B\n\x0bGetResponse\x12\x33\n\ncollection\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"/\n\x0bListRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\"D\n\x0cListResponse\x12\x34\n\x0b\x63ollections\x18\x01 \x03(\x0b\x32\x1f.content.collections.Collection\"D\n\rUpdateRequest\x12\x33\n\ncollection\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"H\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t2\x8d\x03\n\x0b\x43ollections\x12S\n\x06\x43reate\x12\".content.collections.CreateRequest\x1a#.content.collections.CreateResponse\"\x00\x12J\n\x03Get\x12\x1f.content.collections.GetRequest\x1a .content.collections.GetResponse\"\x00\x12M\n\x04List\x12 .content.collections.ListRequest\x1a!.content.collections.ListResponse\"\x00\x12\x46\n\x06Update\x12\".content.collections.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\x06\x44\x65lete\x12\".content.collections.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42:Z8github.com/perxteam/perxis/proto/collections;collectionsb\x06proto3'
+  serialized_pb=b'\n$perxis/collections/collections.proto\x12\x13\x63ontent.collections\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1aperxis/common/common.proto\"s\n\x06\x41\x63\x63\x65ss\x12\x1f\n\x07\x61\x63tions\x18\x01 \x03(\x0e\x32\x0e.common.Action\x12\x15\n\rhidden_fields\x18\x05 \x03(\t\x12\x17\n\x0freadonly_fields\x18\x06 \x03(\t\x12\x18\n\x10writeonly_fields\x18\x07 \x03(\t\"\xca\x02\n\nCollection\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x13\n\x06single\x18\x05 \x01(\x08H\x00\x88\x01\x01\x12\x13\n\x06system\x18\x06 \x01(\x08H\x01\x88\x01\x01\x12\x0e\n\x06schema\x18\x07 \x01(\t\x12\x32\n\x04view\x18\t \x01(\x0b\x32$.content.collections.Collection.View\x12+\n\x06\x61\x63\x63\x65ss\x18\x14 \x01(\x0b\x32\x1b.content.collections.Access\x1aO\n\x04View\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x04 \x01(\tB\t\n\x07_singleB\t\n\x07_system\"D\n\rCreateRequest\x12\x33\n\ncollection\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"B\n\x0e\x43reateResponse\x12\x30\n\x07\x63reated\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"E\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\"B\n\x0bGetResponse\x12\x33\n\ncollection\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"/\n\x0bListRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\"D\n\x0cListResponse\x12\x34\n\x0b\x63ollections\x18\x01 \x03(\x0b\x32\x1f.content.collections.Collection\"D\n\rUpdateRequest\x12\x33\n\ncollection\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\"H\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t2\x8d\x03\n\x0b\x43ollections\x12S\n\x06\x43reate\x12\".content.collections.CreateRequest\x1a#.content.collections.CreateResponse\"\x00\x12J\n\x03Get\x12\x1f.content.collections.GetRequest\x1a .content.collections.GetResponse\"\x00\x12M\n\x04List\x12 .content.collections.ListRequest\x1a!.content.collections.ListResponse\"\x00\x12\x46\n\x06Update\x12\".content.collections.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\x06\x44\x65lete\x12\".content.collections.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42:Z8github.com/perxteam/perxis/proto/collections;collectionsb\x06proto3'
   ,
-  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
+  dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,perxis_dot_common_dot_common__pb2.DESCRIPTOR,])
 
 
 
 
+_ACCESS = _descriptor.Descriptor(
+  name='Access',
+  full_name='content.collections.Access',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='actions', full_name='content.collections.Access.actions', index=0,
+      number=1, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='hidden_fields', full_name='content.collections.Access.hidden_fields', index=1,
+      number=5, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='readonly_fields', full_name='content.collections.Access.readonly_fields', index=2,
+      number=6, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='writeonly_fields', full_name='content.collections.Access.writeonly_fields', index=3,
+      number=7, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=118,
+  serialized_end=233,
+)
+
+
+_COLLECTION_VIEW = _descriptor.Descriptor(
+  name='View',
+  full_name='content.collections.Collection.View',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='space_id', full_name='content.collections.Collection.View.space_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='env_id', full_name='content.collections.Collection.View.env_id', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='collection_id', full_name='content.collections.Collection.View.collection_id', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='filter', full_name='content.collections.Collection.View.filter', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=465,
+  serialized_end=544,
+)
+
 _COLLECTION = _descriptor.Descriptor(
   name='Collection',
   full_name='content.collections.Collection',
@@ -84,10 +190,24 @@ _COLLECTION = _descriptor.Descriptor(
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='view', full_name='content.collections.Collection.view', index=7,
+      number=9, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='access', full_name='content.collections.Collection.access', index=8,
+      number=20, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
   ],
   extensions=[
   ],
-  nested_types=[],
+  nested_types=[_COLLECTION_VIEW, ],
   enum_types=[
   ],
   serialized_options=None,
@@ -106,8 +226,8 @@ _COLLECTION = _descriptor.Descriptor(
       create_key=_descriptor._internal_create_key,
     fields=[]),
   ],
-  serialized_start=91,
-  serialized_end=243,
+  serialized_start=236,
+  serialized_end=566,
 )
 
 
@@ -138,8 +258,8 @@ _CREATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=245,
-  serialized_end=313,
+  serialized_start=568,
+  serialized_end=636,
 )
 
 
@@ -170,8 +290,8 @@ _CREATERESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=315,
-  serialized_end=381,
+  serialized_start=638,
+  serialized_end=704,
 )
 
 
@@ -216,8 +336,8 @@ _GETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=383,
-  serialized_end=452,
+  serialized_start=706,
+  serialized_end=775,
 )
 
 
@@ -248,8 +368,8 @@ _GETRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=454,
-  serialized_end=520,
+  serialized_start=777,
+  serialized_end=843,
 )
 
 
@@ -287,8 +407,8 @@ _LISTREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=522,
-  serialized_end=569,
+  serialized_start=845,
+  serialized_end=892,
 )
 
 
@@ -319,8 +439,8 @@ _LISTRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=571,
-  serialized_end=639,
+  serialized_start=894,
+  serialized_end=962,
 )
 
 
@@ -351,8 +471,8 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=641,
-  serialized_end=709,
+  serialized_start=964,
+  serialized_end=1032,
 )
 
 
@@ -397,10 +517,14 @@ _DELETEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=711,
-  serialized_end=783,
+  serialized_start=1034,
+  serialized_end=1106,
 )
 
+_ACCESS.fields_by_name['actions'].enum_type = perxis_dot_common_dot_common__pb2._ACTION
+_COLLECTION_VIEW.containing_type = _COLLECTION
+_COLLECTION.fields_by_name['view'].message_type = _COLLECTION_VIEW
+_COLLECTION.fields_by_name['access'].message_type = _ACCESS
 _COLLECTION.oneofs_by_name['_single'].fields.append(
   _COLLECTION.fields_by_name['single'])
 _COLLECTION.fields_by_name['single'].containing_oneof = _COLLECTION.oneofs_by_name['_single']
@@ -412,6 +536,7 @@ _CREATERESPONSE.fields_by_name['created'].message_type = _COLLECTION
 _GETRESPONSE.fields_by_name['collection'].message_type = _COLLECTION
 _LISTRESPONSE.fields_by_name['collections'].message_type = _COLLECTION
 _UPDATEREQUEST.fields_by_name['collection'].message_type = _COLLECTION
+DESCRIPTOR.message_types_by_name['Access'] = _ACCESS
 DESCRIPTOR.message_types_by_name['Collection'] = _COLLECTION
 DESCRIPTOR.message_types_by_name['CreateRequest'] = _CREATEREQUEST
 DESCRIPTOR.message_types_by_name['CreateResponse'] = _CREATERESPONSE
@@ -423,12 +548,27 @@ DESCRIPTOR.message_types_by_name['UpdateRequest'] = _UPDATEREQUEST
 DESCRIPTOR.message_types_by_name['DeleteRequest'] = _DELETEREQUEST
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
+Access = _reflection.GeneratedProtocolMessageType('Access', (_message.Message,), {
+  'DESCRIPTOR' : _ACCESS,
+  '__module__' : 'perxis.collections.collections_pb2'
+  # @@protoc_insertion_point(class_scope:content.collections.Access)
+  })
+_sym_db.RegisterMessage(Access)
+
 Collection = _reflection.GeneratedProtocolMessageType('Collection', (_message.Message,), {
+
+  'View' : _reflection.GeneratedProtocolMessageType('View', (_message.Message,), {
+    'DESCRIPTOR' : _COLLECTION_VIEW,
+    '__module__' : 'perxis.collections.collections_pb2'
+    # @@protoc_insertion_point(class_scope:content.collections.Collection.View)
+    })
+  ,
   'DESCRIPTOR' : _COLLECTION,
   '__module__' : 'perxis.collections.collections_pb2'
   # @@protoc_insertion_point(class_scope:content.collections.Collection)
   })
 _sym_db.RegisterMessage(Collection)
+_sym_db.RegisterMessage(Collection.View)
 
 CreateRequest = _reflection.GeneratedProtocolMessageType('CreateRequest', (_message.Message,), {
   'DESCRIPTOR' : _CREATEREQUEST,
@@ -496,8 +636,8 @@ _COLLECTIONS = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=786,
-  serialized_end=1183,
+  serialized_start=1109,
+  serialized_end=1506,
   methods=[
   _descriptor.MethodDescriptor(
     name='Create',
diff --git a/perxis/common/common_pb2.py b/perxis/common/common_pb2.py
index 50b568f080a6b1c2a1acbcfe472e250e506c91d5..844936547905c064a273f58265ee707bf22094b6 100644
--- a/perxis/common/common_pb2.py
+++ b/perxis/common/common_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z.github.com/perxteam/perxis/proto/common;common',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x1aperxis/common/common.proto\x12\x06\x63ommon\x1a\x1cgoogle/protobuf/struct.proto\"\xa6\x05\n\x05\x45rror\x12\x12\n\nerror_code\x18\x01 \x01(\x04\x12\x10\n\x08\x65rror_id\x18\x02 \x01(\t\x12\x0e\n\x06reason\x18\x03 \x01(\t\x12\x0e\n\x06\x64omain\x18\x04 \x01(\t\x12-\n\x08metadata\x18\t \x03(\x0b\x32\x1b.common.Error.MetadataEntry\x12-\n\x0b\x62\x61\x64_request\x18\n \x01(\x0b\x32\x18.common.Error.BadRequest\x12+\n\ndebug_info\x18\x0b \x01(\x0b\x32\x17.common.Error.DebugInfo\x12 \n\x04help\x18\x64 \x01(\x0b\x32\x12.common.Error.Help\x12;\n\x12localized_messages\x18\xc8\x01 \x03(\x0b\x32\x1e.common.Error.LocalizedMessage\x1a{\n\nBadRequest\x12\x37\n\x06\x65rrors\x18\x01 \x03(\x0b\x32\'.common.Error.BadRequest.FieldViolation\x1a\x34\n\x0e\x46ieldViolation\x12\r\n\x05\x66ield\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x1aX\n\x04Help\x12&\n\x05links\x18\x01 \x03(\x0b\x32\x17.common.Error.Help.Link\x1a(\n\x04Link\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x1a\x30\n\tDebugInfo\x12\x13\n\x0bstack_trace\x18\x01 \x03(\t\x12\x0e\n\x06\x64\x65tail\x18\x02 \x01(\t\x1a\x33\n\x10LocalizedMessage\x12\x0e\n\x06locale\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x06\x46ilter\x12\n\n\x02op\x18\x01 \x01(\t\x12\r\n\x05\x66ield\x18\x02 \x01(\t\x12%\n\x05value\x18\x03 \x01(\x0b\x32\x16.google.protobuf.Value\"@\n\x0b\x46indOptions\x12\x0c\n\x04sort\x18\x01 \x03(\t\x12\x10\n\x08page_num\x18\x02 \x01(\x05\x12\x11\n\tpage_size\x18\x03 \x01(\x05\"\xa8\x01\n\x04Rule\x12\x15\n\rcollection_id\x18\x01 \x01(\t\x12\x1f\n\x07\x61\x63tions\x18\x02 \x03(\x0e\x32\x0e.common.Action\x12\x1e\n\x06\x61\x63\x63\x65ss\x18\x03 \x01(\x0e\x32\x0e.common.Access\x12\x15\n\rhidden_fields\x18\x05 \x03(\t\x12\x17\n\x0freadonly_fields\x18\x06 \x03(\t\x12\x18\n\x10writeonly_fields\x18\x07 \x03(\t\"?\n\x0c\x43ollaborator\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12\x0c\n\x04role\x18\x03 \x01(\t\"p\n\x07Version\x12\x16\n\x0eserver_version\x18\x01 \x01(\t\x12\x13\n\x0b\x61pi_version\x18\x02 \x01(\t\x12\x12\n\nbuild_time\x18\x03 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x04 \x01(\t\x12\x14\n\x0c\x62uild_number\x18\x05 \x01(\x05*%\n\x06\x41\x63\x63\x65ss\x12\x07\n\x03\x41NY\x10\x00\x12\x08\n\x04MINE\x10\x01\x12\x08\n\x04ROLE\x10\x02*C\n\x06\x41\x63tion\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x43REATE\x10\x01\x12\x08\n\x04READ\x10\x02\x12\n\n\x06UPDATE\x10\x03\x12\n\n\x06\x44\x45LETE\x10\x04\x42\x30Z.github.com/perxteam/perxis/proto/common;commonb\x06proto3'
+  serialized_pb=b'\n\x1aperxis/common/common.proto\x12\x06\x63ommon\x1a\x1cgoogle/protobuf/struct.proto\"\xa6\x05\n\x05\x45rror\x12\x12\n\nerror_code\x18\x01 \x01(\x04\x12\x10\n\x08\x65rror_id\x18\x02 \x01(\t\x12\x0e\n\x06reason\x18\x03 \x01(\t\x12\x0e\n\x06\x64omain\x18\x04 \x01(\t\x12-\n\x08metadata\x18\t \x03(\x0b\x32\x1b.common.Error.MetadataEntry\x12-\n\x0b\x62\x61\x64_request\x18\n \x01(\x0b\x32\x18.common.Error.BadRequest\x12+\n\ndebug_info\x18\x0b \x01(\x0b\x32\x17.common.Error.DebugInfo\x12 \n\x04help\x18\x64 \x01(\x0b\x32\x12.common.Error.Help\x12;\n\x12localized_messages\x18\xc8\x01 \x03(\x0b\x32\x1e.common.Error.LocalizedMessage\x1a{\n\nBadRequest\x12\x37\n\x06\x65rrors\x18\x01 \x03(\x0b\x32\'.common.Error.BadRequest.FieldViolation\x1a\x34\n\x0e\x46ieldViolation\x12\r\n\x05\x66ield\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x1aX\n\x04Help\x12&\n\x05links\x18\x01 \x03(\x0b\x32\x17.common.Error.Help.Link\x1a(\n\x04Link\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x1a\x30\n\tDebugInfo\x12\x13\n\x0bstack_trace\x18\x01 \x03(\t\x12\x0e\n\x06\x64\x65tail\x18\x02 \x01(\t\x1a\x33\n\x10LocalizedMessage\x12\x0e\n\x06locale\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"J\n\x06\x46ilter\x12\n\n\x02op\x18\x01 \x01(\t\x12\r\n\x05\x66ield\x18\x02 \x01(\t\x12%\n\x05value\x18\x03 \x01(\x0b\x32\x16.google.protobuf.Value\"@\n\x0b\x46indOptions\x12\x0c\n\x04sort\x18\x01 \x03(\t\x12\x10\n\x08page_num\x18\x02 \x01(\x05\x12\x11\n\tpage_size\x18\x03 \x01(\x05\"\xb8\x01\n\x04Rule\x12\x15\n\rcollection_id\x18\x01 \x01(\t\x12\x1f\n\x07\x61\x63tions\x18\x02 \x03(\x0e\x32\x0e.common.Action\x12\x1e\n\x06\x61\x63\x63\x65ss\x18\x03 \x01(\x0e\x32\x0e.common.Access\x12\x15\n\rhidden_fields\x18\x05 \x03(\t\x12\x17\n\x0freadonly_fields\x18\x06 \x03(\t\x12\x18\n\x10writeonly_fields\x18\x07 \x03(\t\x12\x0e\n\x06\x66ilter\x18\x08 \x01(\t\"?\n\x0c\x43ollaborator\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0f\n\x07user_id\x18\x02 \x01(\t\x12\x0c\n\x04role\x18\x03 \x01(\t\"p\n\x07Version\x12\x16\n\x0eserver_version\x18\x01 \x01(\t\x12\x13\n\x0b\x61pi_version\x18\x02 \x01(\t\x12\x12\n\nbuild_time\x18\x03 \x01(\t\x12\x0e\n\x06\x63ommit\x18\x04 \x01(\t\x12\x14\n\x0c\x62uild_number\x18\x05 \x01(\x05*%\n\x06\x41\x63\x63\x65ss\x12\x07\n\x03\x41NY\x10\x00\x12\x08\n\x04MINE\x10\x01\x12\x08\n\x04ROLE\x10\x02*C\n\x06\x41\x63tion\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06\x43REATE\x10\x01\x12\x08\n\x04READ\x10\x02\x12\n\n\x06UPDATE\x10\x03\x12\n\n\x06\x44\x45LETE\x10\x04\x42\x30Z.github.com/perxteam/perxis/proto/common;commonb\x06proto3'
   ,
   dependencies=[google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,])
 
@@ -50,8 +50,8 @@ _ACCESS = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=1241,
-  serialized_end=1278,
+  serialized_start=1257,
+  serialized_end=1294,
 )
 _sym_db.RegisterEnumDescriptor(_ACCESS)
 
@@ -91,8 +91,8 @@ _ACTION = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=1280,
-  serialized_end=1347,
+  serialized_start=1296,
+  serialized_end=1363,
 )
 _sym_db.RegisterEnumDescriptor(_ACTION)
 
@@ -590,6 +590,13 @@ _RULE = _descriptor.Descriptor(
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='filter', full_name='common.Rule.filter', index=6,
+      number=8, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
   ],
   extensions=[
   ],
@@ -603,7 +610,7 @@ _RULE = _descriptor.Descriptor(
   oneofs=[
   ],
   serialized_start=892,
-  serialized_end=1060,
+  serialized_end=1076,
 )
 
 
@@ -648,8 +655,8 @@ _COLLABORATOR = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1062,
-  serialized_end=1125,
+  serialized_start=1078,
+  serialized_end=1141,
 )
 
 
@@ -708,8 +715,8 @@ _VERSION = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1127,
-  serialized_end=1239,
+  serialized_start=1143,
+  serialized_end=1255,
 )
 
 _ERROR_BADREQUEST_FIELDVIOLATION.containing_type = _ERROR_BADREQUEST
diff --git a/perxis/delivery/delivery_pb2.py b/perxis/delivery/delivery_pb2.py
index 469db22e243765b0c30cf06452a6db8ee0c62cec..308232e00cf6d465a3c36a37502d2f1923e3adf8 100644
--- a/perxis/delivery/delivery_pb2.py
+++ b/perxis/delivery/delivery_pb2.py
@@ -15,7 +15,6 @@ from perxis.locales import locales_pb2 as perxis_dot_locales_dot_locales__pb2
 from perxis.environments import environments_pb2 as perxis_dot_environments_dot_environments__pb2
 from perxis.collections import collections_pb2 as perxis_dot_collections_dot_collections__pb2
 from perxis.items import items_pb2 as perxis_dot_items_dot_items__pb2
-from perxis.common import common_pb2 as perxis_dot_common_dot_common__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
@@ -24,9 +23,9 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z2github.com/perxteam/perxis/proto/delivery;delivery',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x1eperxis/delivery/delivery.proto\x12\x08\x64\x65livery\x1a\x1cperxis/locales/locales.proto\x1a&perxis/environments/environments.proto\x1a$perxis/collections/collections.proto\x1a\x18perxis/items/items.proto\x1a\x1aperxis/common/common.proto\"&\n\x12ListLocalesRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"?\n\x13ListLocalesResponse\x12(\n\x07locales\x18\x01 \x03(\x0b\x32\x17.content.locales.Locale\"9\n\x15GetEnvironmentRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\"H\n\x16GetEnvironmentResponse\x12.\n\x03\x65nv\x18\x01 \x01(\x0b\x32!.content.environments.Environment\"+\n\x17ListEnvironmentsRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"K\n\x18ListEnvironmentsResponse\x12/\n\x04\x65nvs\x18\x01 \x03(\x0b\x32!.content.environments.Environment\"O\n\x14GetCollectionRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\"L\n\x15GetCollectionResponse\x12\x33\n\ncollection\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\":\n\x16ListCollectionsRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\"O\n\x17ListCollectionsResponse\x12\x34\n\x0b\x63ollections\x18\x01 \x03(\x0b\x32\x1f.content.collections.Collection\"m\n\x0eGetItemRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x11\n\tlocale_id\x18\x04 \x01(\t\x12\x0f\n\x07item_id\x18\x05 \x01(\t\"4\n\x0fGetItemResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\xab\x01\n\x10\x46indItemsRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x11\n\tlocale_id\x18\x04 \x01(\t\x12%\n\x06\x66ilter\x18\x05 \x01(\x0b\x32\x15.content.items.Filter\x12$\n\x07options\x18\x06 \x01(\x0b\x32\x13.common.FindOptions\"F\n\x11\x46indItemsResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\x12\r\n\x05total\x18\x02 \x01(\x05\x32\xc4\x04\n\x08\x44\x65livery\x12L\n\x0bListLocales\x12\x1c.delivery.ListLocalesRequest\x1a\x1d.delivery.ListLocalesResponse\"\x00\x12U\n\x0eGetEnvironment\x12\x1f.delivery.GetEnvironmentRequest\x1a .delivery.GetEnvironmentResponse\"\x00\x12[\n\x10ListEnvironments\x12!.delivery.ListEnvironmentsRequest\x1a\".delivery.ListEnvironmentsResponse\"\x00\x12R\n\rGetCollection\x12\x1e.delivery.GetCollectionRequest\x1a\x1f.delivery.GetCollectionResponse\"\x00\x12X\n\x0fListCollections\x12 .delivery.ListCollectionsRequest\x1a!.delivery.ListCollectionsResponse\"\x00\x12@\n\x07GetItem\x12\x18.delivery.GetItemRequest\x1a\x19.delivery.GetItemResponse\"\x00\x12\x46\n\tFindItems\x12\x1a.delivery.FindItemsRequest\x1a\x1b.delivery.FindItemsResponse\"\x00\x42\x34Z2github.com/perxteam/perxis/proto/delivery;deliveryb\x06proto3'
+  serialized_pb=b'\n\x1eperxis/delivery/delivery.proto\x12\x08\x64\x65livery\x1a\x1cperxis/locales/locales.proto\x1a&perxis/environments/environments.proto\x1a$perxis/collections/collections.proto\x1a\x18perxis/items/items.proto\"&\n\x12ListLocalesRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"?\n\x13ListLocalesResponse\x12(\n\x07locales\x18\x01 \x03(\x0b\x32\x17.content.locales.Locale\"9\n\x15GetEnvironmentRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\"H\n\x16GetEnvironmentResponse\x12.\n\x03\x65nv\x18\x01 \x01(\x0b\x32!.content.environments.Environment\"+\n\x17ListEnvironmentsRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"K\n\x18ListEnvironmentsResponse\x12/\n\x04\x65nvs\x18\x01 \x03(\x0b\x32!.content.environments.Environment\"O\n\x14GetCollectionRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\"L\n\x15GetCollectionResponse\x12\x33\n\ncollection\x18\x01 \x01(\x0b\x32\x1f.content.collections.Collection\":\n\x16ListCollectionsRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\"O\n\x17ListCollectionsResponse\x12\x34\n\x0b\x63ollections\x18\x01 \x03(\x0b\x32\x1f.content.collections.Collection\"\x8f\x01\n\x0eGetItemRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x05 \x01(\t\x12\x33\n\x07options\x18\x06 \x01(\x0b\x32\".content.items.GetPublishedOptions\"4\n\x0fGetItemResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\xbb\x01\n\x10\x46indItemsRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x11\n\tlocale_id\x18\x04 \x01(\t\x12%\n\x06\x66ilter\x18\x05 \x01(\x0b\x32\x15.content.items.Filter\x12\x34\n\x07options\x18\x06 \x01(\x0b\x32#.content.items.FindPublishedOptions\"F\n\x11\x46indItemsResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\x12\r\n\x05total\x18\x02 \x01(\x05\x32\xc4\x04\n\x08\x44\x65livery\x12L\n\x0bListLocales\x12\x1c.delivery.ListLocalesRequest\x1a\x1d.delivery.ListLocalesResponse\"\x00\x12U\n\x0eGetEnvironment\x12\x1f.delivery.GetEnvironmentRequest\x1a .delivery.GetEnvironmentResponse\"\x00\x12[\n\x10ListEnvironments\x12!.delivery.ListEnvironmentsRequest\x1a\".delivery.ListEnvironmentsResponse\"\x00\x12R\n\rGetCollection\x12\x1e.delivery.GetCollectionRequest\x1a\x1f.delivery.GetCollectionResponse\"\x00\x12X\n\x0fListCollections\x12 .delivery.ListCollectionsRequest\x1a!.delivery.ListCollectionsResponse\"\x00\x12@\n\x07GetItem\x12\x18.delivery.GetItemRequest\x1a\x19.delivery.GetItemResponse\"\x00\x12\x46\n\tFindItems\x12\x1a.delivery.FindItemsRequest\x1a\x1b.delivery.FindItemsResponse\"\x00\x42\x34Z2github.com/perxteam/perxis/proto/delivery;deliveryb\x06proto3'
   ,
-  dependencies=[perxis_dot_locales_dot_locales__pb2.DESCRIPTOR,perxis_dot_environments_dot_environments__pb2.DESCRIPTOR,perxis_dot_collections_dot_collections__pb2.DESCRIPTOR,perxis_dot_items_dot_items__pb2.DESCRIPTOR,perxis_dot_common_dot_common__pb2.DESCRIPTOR,])
+  dependencies=[perxis_dot_locales_dot_locales__pb2.DESCRIPTOR,perxis_dot_environments_dot_environments__pb2.DESCRIPTOR,perxis_dot_collections_dot_collections__pb2.DESCRIPTOR,perxis_dot_items_dot_items__pb2.DESCRIPTOR,])
 
 
 
@@ -58,8 +57,8 @@ _LISTLOCALESREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=206,
-  serialized_end=244,
+  serialized_start=178,
+  serialized_end=216,
 )
 
 
@@ -90,8 +89,8 @@ _LISTLOCALESRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=246,
-  serialized_end=309,
+  serialized_start=218,
+  serialized_end=281,
 )
 
 
@@ -129,8 +128,8 @@ _GETENVIRONMENTREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=311,
-  serialized_end=368,
+  serialized_start=283,
+  serialized_end=340,
 )
 
 
@@ -161,8 +160,8 @@ _GETENVIRONMENTRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=370,
-  serialized_end=442,
+  serialized_start=342,
+  serialized_end=414,
 )
 
 
@@ -193,8 +192,8 @@ _LISTENVIRONMENTSREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=444,
-  serialized_end=487,
+  serialized_start=416,
+  serialized_end=459,
 )
 
 
@@ -225,8 +224,8 @@ _LISTENVIRONMENTSRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=489,
-  serialized_end=564,
+  serialized_start=461,
+  serialized_end=536,
 )
 
 
@@ -271,8 +270,8 @@ _GETCOLLECTIONREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=566,
-  serialized_end=645,
+  serialized_start=538,
+  serialized_end=617,
 )
 
 
@@ -303,8 +302,8 @@ _GETCOLLECTIONRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=647,
-  serialized_end=723,
+  serialized_start=619,
+  serialized_end=695,
 )
 
 
@@ -342,8 +341,8 @@ _LISTCOLLECTIONSREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=725,
-  serialized_end=783,
+  serialized_start=697,
+  serialized_end=755,
 )
 
 
@@ -374,8 +373,8 @@ _LISTCOLLECTIONSRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=785,
-  serialized_end=864,
+  serialized_start=757,
+  serialized_end=836,
 )
 
 
@@ -409,16 +408,16 @@ _GETITEMREQUEST = _descriptor.Descriptor(
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='locale_id', full_name='delivery.GetItemRequest.locale_id', index=3,
-      number=4, type=9, cpp_type=9, label=1,
+      name='item_id', full_name='delivery.GetItemRequest.item_id', index=3,
+      number=5, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='item_id', full_name='delivery.GetItemRequest.item_id', index=4,
-      number=5, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
+      name='options', full_name='delivery.GetItemRequest.options', index=4,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
@@ -434,8 +433,8 @@ _GETITEMREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=866,
-  serialized_end=975,
+  serialized_start=839,
+  serialized_end=982,
 )
 
 
@@ -466,8 +465,8 @@ _GETITEMRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=977,
-  serialized_end=1029,
+  serialized_start=984,
+  serialized_end=1036,
 )
 
 
@@ -533,8 +532,8 @@ _FINDITEMSREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1032,
-  serialized_end=1203,
+  serialized_start=1039,
+  serialized_end=1226,
 )
 
 
@@ -572,8 +571,8 @@ _FINDITEMSRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1205,
-  serialized_end=1275,
+  serialized_start=1228,
+  serialized_end=1298,
 )
 
 _LISTLOCALESRESPONSE.fields_by_name['locales'].message_type = perxis_dot_locales_dot_locales__pb2._LOCALE
@@ -581,9 +580,10 @@ _GETENVIRONMENTRESPONSE.fields_by_name['env'].message_type = perxis_dot_environm
 _LISTENVIRONMENTSRESPONSE.fields_by_name['envs'].message_type = perxis_dot_environments_dot_environments__pb2._ENVIRONMENT
 _GETCOLLECTIONRESPONSE.fields_by_name['collection'].message_type = perxis_dot_collections_dot_collections__pb2._COLLECTION
 _LISTCOLLECTIONSRESPONSE.fields_by_name['collections'].message_type = perxis_dot_collections_dot_collections__pb2._COLLECTION
+_GETITEMREQUEST.fields_by_name['options'].message_type = perxis_dot_items_dot_items__pb2._GETPUBLISHEDOPTIONS
 _GETITEMRESPONSE.fields_by_name['item'].message_type = perxis_dot_items_dot_items__pb2._ITEM
 _FINDITEMSREQUEST.fields_by_name['filter'].message_type = perxis_dot_items_dot_items__pb2._FILTER
-_FINDITEMSREQUEST.fields_by_name['options'].message_type = perxis_dot_common_dot_common__pb2._FINDOPTIONS
+_FINDITEMSREQUEST.fields_by_name['options'].message_type = perxis_dot_items_dot_items__pb2._FINDPUBLISHEDOPTIONS
 _FINDITEMSRESPONSE.fields_by_name['items'].message_type = perxis_dot_items_dot_items__pb2._ITEM
 DESCRIPTOR.message_types_by_name['ListLocalesRequest'] = _LISTLOCALESREQUEST
 DESCRIPTOR.message_types_by_name['ListLocalesResponse'] = _LISTLOCALESRESPONSE
@@ -709,8 +709,8 @@ _DELIVERY = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=1278,
-  serialized_end=1858,
+  serialized_start=1301,
+  serialized_end=1881,
   methods=[
   _descriptor.MethodDescriptor(
     name='ListLocales',
diff --git a/perxis/file/__init__.py b/perxis/features/__init__.py
similarity index 100%
rename from perxis/file/__init__.py
rename to perxis/features/__init__.py
diff --git a/perxis/features/features_pb2.py b/perxis/features/features_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..21b8fefd3996ef0d413165c9592cf72700e1716c
--- /dev/null
+++ b/perxis/features/features_pb2.py
@@ -0,0 +1,185 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: perxis/features/features.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='perxis/features/features.proto',
+  package='content.features',
+  syntax='proto3',
+  serialized_options=b'Z2github.com/perxteam/perxis/proto/features;features',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x1eperxis/features/features.proto\x12\x10\x63ontent.features\"J\n\x12\x46\x65\x61tureDescription\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x10\n\x08revision\x18\x02 \x01(\t\x12\x14\n\x0c\x64\x65pendencies\x18\x03 \x03(\t\"\r\n\x0bListRequest\"J\n\x0cListResponse\x12:\n\x0c\x64\x65scriptions\x18\x01 \x03(\x0b\x32$.content.features.FeatureDescription2S\n\x08\x46\x65\x61tures\x12G\n\x04List\x12\x1d.content.features.ListRequest\x1a\x1e.content.features.ListResponse\"\x00\x42\x34Z2github.com/perxteam/perxis/proto/features;featuresb\x06proto3'
+)
+
+
+
+
+_FEATUREDESCRIPTION = _descriptor.Descriptor(
+  name='FeatureDescription',
+  full_name='content.features.FeatureDescription',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='content.features.FeatureDescription.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='revision', full_name='content.features.FeatureDescription.revision', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='dependencies', full_name='content.features.FeatureDescription.dependencies', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=52,
+  serialized_end=126,
+)
+
+
+_LISTREQUEST = _descriptor.Descriptor(
+  name='ListRequest',
+  full_name='content.features.ListRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=128,
+  serialized_end=141,
+)
+
+
+_LISTRESPONSE = _descriptor.Descriptor(
+  name='ListResponse',
+  full_name='content.features.ListResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='descriptions', full_name='content.features.ListResponse.descriptions', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=143,
+  serialized_end=217,
+)
+
+_LISTRESPONSE.fields_by_name['descriptions'].message_type = _FEATUREDESCRIPTION
+DESCRIPTOR.message_types_by_name['FeatureDescription'] = _FEATUREDESCRIPTION
+DESCRIPTOR.message_types_by_name['ListRequest'] = _LISTREQUEST
+DESCRIPTOR.message_types_by_name['ListResponse'] = _LISTRESPONSE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+FeatureDescription = _reflection.GeneratedProtocolMessageType('FeatureDescription', (_message.Message,), {
+  'DESCRIPTOR' : _FEATUREDESCRIPTION,
+  '__module__' : 'perxis.features.features_pb2'
+  # @@protoc_insertion_point(class_scope:content.features.FeatureDescription)
+  })
+_sym_db.RegisterMessage(FeatureDescription)
+
+ListRequest = _reflection.GeneratedProtocolMessageType('ListRequest', (_message.Message,), {
+  'DESCRIPTOR' : _LISTREQUEST,
+  '__module__' : 'perxis.features.features_pb2'
+  # @@protoc_insertion_point(class_scope:content.features.ListRequest)
+  })
+_sym_db.RegisterMessage(ListRequest)
+
+ListResponse = _reflection.GeneratedProtocolMessageType('ListResponse', (_message.Message,), {
+  'DESCRIPTOR' : _LISTRESPONSE,
+  '__module__' : 'perxis.features.features_pb2'
+  # @@protoc_insertion_point(class_scope:content.features.ListResponse)
+  })
+_sym_db.RegisterMessage(ListResponse)
+
+
+DESCRIPTOR._options = None
+
+_FEATURES = _descriptor.ServiceDescriptor(
+  name='Features',
+  full_name='content.features.Features',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=219,
+  serialized_end=302,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='List',
+    full_name='content.features.Features.List',
+    index=0,
+    containing_service=None,
+    input_type=_LISTREQUEST,
+    output_type=_LISTRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_FEATURES)
+
+DESCRIPTOR.services_by_name['Features'] = _FEATURES
+
+# @@protoc_insertion_point(module_scope)
diff --git a/perxis/features/features_pb2_grpc.py b/perxis/features/features_pb2_grpc.py
new file mode 100644
index 0000000000000000000000000000000000000000..cceb7509bbb4c10f318355ae5649b5ac667884c3
--- /dev/null
+++ b/perxis/features/features_pb2_grpc.py
@@ -0,0 +1,67 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+from perxis.features import features_pb2 as perxis_dot_features_dot_features__pb2
+
+
+class FeaturesStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.List = channel.unary_unary(
+                '/content.features.Features/List',
+                request_serializer=perxis_dot_features_dot_features__pb2.ListRequest.SerializeToString,
+                response_deserializer=perxis_dot_features_dot_features__pb2.ListResponse.FromString,
+                )
+
+
+class FeaturesServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def List(self, request, context):
+        """List получить все возможности зарегистрированные в системе
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_FeaturesServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'List': grpc.unary_unary_rpc_method_handler(
+                    servicer.List,
+                    request_deserializer=perxis_dot_features_dot_features__pb2.ListRequest.FromString,
+                    response_serializer=perxis_dot_features_dot_features__pb2.ListResponse.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'content.features.Features', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class Features(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def List(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.features.Features/List',
+            perxis_dot_features_dot_features__pb2.ListRequest.SerializeToString,
+            perxis_dot_features_dot_features__pb2.ListResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/perxis/files/__init__.py b/perxis/files/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/perxis/file/file_pb2.py b/perxis/files/files_pb2.py
similarity index 73%
rename from perxis/file/file_pb2.py
rename to perxis/files/files_pb2.py
index 3d480847139d1fb373690aeb26d0ced55a7a9c82..c78258bbc1d09c6dcaecb89fb3e3a4c2d4e0d26d 100644
--- a/perxis/file/file_pb2.py
+++ b/perxis/files/files_pb2.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
-# source: perxis/file/file.proto
+# source: perxis/files/files.proto
 """Generated protocol buffer code."""
 from google.protobuf import descriptor as _descriptor
 from google.protobuf import message as _message
@@ -15,12 +15,12 @@ from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
-  name='perxis/file/file.proto',
-  package='file',
+  name='perxis/files/files.proto',
+  package='files',
   syntax='proto3',
-  serialized_options=b'Z*github.com/perxteam/perxis/proto/file;file',
+  serialized_options=b'Z,github.com/perxteam/perxis/proto/files;files',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x16perxis/file/file.proto\x12\x04\x66ile\x1a\x1bgoogle/protobuf/empty.proto\"N\n\x04\x46ile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04size\x18\x03 \x01(\x05\x12\x11\n\tmime_type\x18\x04 \x01(\t\x12\x0b\n\x03url\x18\x05 \x01(\t\"\x88\x01\n\x0fMultipartUpload\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12\x11\n\tupload_id\x18\x02 \x01(\t\x12\x11\n\tpart_size\x18\x03 \x01(\x05\x12\x11\n\tpart_urls\x18\x04 \x03(\t\x12\"\n\x05parts\x18\x05 \x03(\x0b\x32\x13.file.CompletedPart\"6\n\x06Upload\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12\x12\n\nupload_url\x18\x02 \x01(\t\"+\n\rCompletedPart\x12\x0e\n\x06number\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\t\";\n\x12StartUploadRequest\x12%\n\x06upload\x18\x01 \x01(\x0b\x32\x15.file.MultipartUpload\"<\n\x13StartUploadResponse\x12%\n\x06upload\x18\x01 \x01(\x0b\x32\x15.file.MultipartUpload\">\n\x15\x43ompleteUploadRequest\x12%\n\x06upload\x18\x01 \x01(\x0b\x32\x15.file.MultipartUpload\"?\n\x16\x43ompleteUploadResponse\x12%\n\x06upload\x18\x01 \x01(\x0b\x32\x15.file.MultipartUpload\";\n\x12\x41\x62ortUploadRequest\x12%\n\x06upload\x18\x01 \x01(\x0b\x32\x15.file.MultipartUpload\"\x15\n\x13\x41\x62ortUploadResponse\":\n\x11MoveUploadRequest\x12%\n\x06upload\x18\x01 \x01(\x0b\x32\x15.file.MultipartUpload\".\n\x12MoveUploadResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\")\n\rUploadRequest\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\".\n\x0eUploadResponse\x12\x1c\n\x06upload\x18\x01 \x01(\x0b\x32\x0c.file.Upload\"\x1c\n\x0eGetFileRequest\x12\n\n\x02id\x18\x01 \x01(\t\"+\n\x0fGetFileResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\"-\n\x11\x44\x65leteFileRequest\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\"\x14\n\x12\x44\x65leteFileResponse2\xda\x03\n\x0b\x46ileService\x12\x44\n\x0bStartUpload\x12\x18.file.StartUploadRequest\x1a\x19.file.StartUploadResponse\"\x00\x12M\n\x0e\x43ompleteUpload\x12\x1b.file.CompleteUploadRequest\x1a\x1c.file.CompleteUploadResponse\"\x00\x12\x41\n\x0b\x41\x62ortUpload\x12\x18.file.AbortUploadRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x41\n\nMoveUpload\x12\x17.file.MoveUploadRequest\x1a\x18.file.MoveUploadResponse\"\x00\x12\x35\n\x06Upload\x12\x13.file.UploadRequest\x1a\x14.file.UploadResponse\"\x00\x12\x38\n\x07GetFile\x12\x14.file.GetFileRequest\x1a\x15.file.GetFileResponse\"\x00\x12?\n\nDeleteFile\x12\x17.file.DeleteFileRequest\x1a\x16.google.protobuf.Empty\"\x00\x42,Z*github.com/perxteam/perxis/proto/file;fileb\x06proto3'
+  serialized_pb=b'\n\x18perxis/files/files.proto\x12\x05\x66iles\x1a\x1bgoogle/protobuf/empty.proto\"N\n\x04\x46ile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04size\x18\x03 \x01(\x05\x12\x11\n\tmime_type\x18\x04 \x01(\t\x12\x0b\n\x03url\x18\x05 \x01(\t\"\x8a\x01\n\x0fMultipartUpload\x12\x19\n\x04\x66ile\x18\x01 \x01(\x0b\x32\x0b.files.File\x12\x11\n\tupload_id\x18\x02 \x01(\t\x12\x11\n\tpart_size\x18\x03 \x01(\x05\x12\x11\n\tpart_urls\x18\x04 \x03(\t\x12#\n\x05parts\x18\x05 \x03(\x0b\x32\x14.files.CompletedPart\"7\n\x06Upload\x12\x19\n\x04\x66ile\x18\x01 \x01(\x0b\x32\x0b.files.File\x12\x12\n\nupload_url\x18\x02 \x01(\t\"+\n\rCompletedPart\x12\x0e\n\x06number\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\t\"<\n\x12StartUploadRequest\x12&\n\x06upload\x18\x01 \x01(\x0b\x32\x16.files.MultipartUpload\"=\n\x13StartUploadResponse\x12&\n\x06upload\x18\x01 \x01(\x0b\x32\x16.files.MultipartUpload\"?\n\x15\x43ompleteUploadRequest\x12&\n\x06upload\x18\x01 \x01(\x0b\x32\x16.files.MultipartUpload\"@\n\x16\x43ompleteUploadResponse\x12&\n\x06upload\x18\x01 \x01(\x0b\x32\x16.files.MultipartUpload\"<\n\x12\x41\x62ortUploadRequest\x12&\n\x06upload\x18\x01 \x01(\x0b\x32\x16.files.MultipartUpload\"\x15\n\x13\x41\x62ortUploadResponse\";\n\x11MoveUploadRequest\x12&\n\x06upload\x18\x01 \x01(\x0b\x32\x16.files.MultipartUpload\"/\n\x12MoveUploadResponse\x12\x19\n\x04\x66ile\x18\x01 \x01(\x0b\x32\x0b.files.File\"*\n\rUploadRequest\x12\x19\n\x04\x66ile\x18\x01 \x01(\x0b\x32\x0b.files.File\"/\n\x0eUploadResponse\x12\x1d\n\x06upload\x18\x01 \x01(\x0b\x32\r.files.Upload\"\x1c\n\x0eGetFileRequest\x12\n\n\x02id\x18\x01 \x01(\t\",\n\x0fGetFileResponse\x12\x19\n\x04\x66ile\x18\x01 \x01(\x0b\x32\x0b.files.File\".\n\x11\x44\x65leteFileRequest\x12\x19\n\x04\x66ile\x18\x01 \x01(\x0b\x32\x0b.files.File\"\x14\n\x12\x44\x65leteFileResponse2\xe0\x03\n\x05\x46iles\x12\x46\n\x0bStartUpload\x12\x19.files.StartUploadRequest\x1a\x1a.files.StartUploadResponse\"\x00\x12O\n\x0e\x43ompleteUpload\x12\x1c.files.CompleteUploadRequest\x1a\x1d.files.CompleteUploadResponse\"\x00\x12\x42\n\x0b\x41\x62ortUpload\x12\x19.files.AbortUploadRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x43\n\nMoveUpload\x12\x18.files.MoveUploadRequest\x1a\x19.files.MoveUploadResponse\"\x00\x12\x37\n\x06Upload\x12\x14.files.UploadRequest\x1a\x15.files.UploadResponse\"\x00\x12:\n\x07GetFile\x12\x15.files.GetFileRequest\x1a\x16.files.GetFileResponse\"\x00\x12@\n\nDeleteFile\x12\x18.files.DeleteFileRequest\x1a\x16.google.protobuf.Empty\"\x00\x42.Z,github.com/perxteam/perxis/proto/files;filesb\x06proto3'
   ,
   dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
 
@@ -29,42 +29,42 @@ DESCRIPTOR = _descriptor.FileDescriptor(
 
 _FILE = _descriptor.Descriptor(
   name='File',
-  full_name='file.File',
+  full_name='files.File',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='id', full_name='file.File.id', index=0,
+      name='id', full_name='files.File.id', index=0,
       number=1, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='name', full_name='file.File.name', index=1,
+      name='name', full_name='files.File.name', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='size', full_name='file.File.size', index=2,
+      name='size', full_name='files.File.size', index=2,
       number=3, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='mime_type', full_name='file.File.mime_type', index=3,
+      name='mime_type', full_name='files.File.mime_type', index=3,
       number=4, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='url', full_name='file.File.url', index=4,
+      name='url', full_name='files.File.url', index=4,
       number=5, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
@@ -82,49 +82,49 @@ _FILE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=61,
-  serialized_end=139,
+  serialized_start=64,
+  serialized_end=142,
 )
 
 
 _MULTIPARTUPLOAD = _descriptor.Descriptor(
   name='MultipartUpload',
-  full_name='file.MultipartUpload',
+  full_name='files.MultipartUpload',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='file', full_name='file.MultipartUpload.file', index=0,
+      name='file', full_name='files.MultipartUpload.file', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='upload_id', full_name='file.MultipartUpload.upload_id', index=1,
+      name='upload_id', full_name='files.MultipartUpload.upload_id', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='part_size', full_name='file.MultipartUpload.part_size', index=2,
+      name='part_size', full_name='files.MultipartUpload.part_size', index=2,
       number=3, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='part_urls', full_name='file.MultipartUpload.part_urls', index=3,
+      name='part_urls', full_name='files.MultipartUpload.part_urls', index=3,
       number=4, type=9, cpp_type=9, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='parts', full_name='file.MultipartUpload.parts', index=4,
+      name='parts', full_name='files.MultipartUpload.parts', index=4,
       number=5, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
@@ -142,28 +142,28 @@ _MULTIPARTUPLOAD = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=142,
-  serialized_end=278,
+  serialized_start=145,
+  serialized_end=283,
 )
 
 
 _UPLOAD = _descriptor.Descriptor(
   name='Upload',
-  full_name='file.Upload',
+  full_name='files.Upload',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='file', full_name='file.Upload.file', index=0,
+      name='file', full_name='files.Upload.file', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='upload_url', full_name='file.Upload.upload_url', index=1,
+      name='upload_url', full_name='files.Upload.upload_url', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
@@ -181,28 +181,28 @@ _UPLOAD = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=280,
-  serialized_end=334,
+  serialized_start=285,
+  serialized_end=340,
 )
 
 
 _COMPLETEDPART = _descriptor.Descriptor(
   name='CompletedPart',
-  full_name='file.CompletedPart',
+  full_name='files.CompletedPart',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='number', full_name='file.CompletedPart.number', index=0,
+      name='number', full_name='files.CompletedPart.number', index=0,
       number=1, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='id', full_name='file.CompletedPart.id', index=1,
+      name='id', full_name='files.CompletedPart.id', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
@@ -220,21 +220,21 @@ _COMPLETEDPART = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=336,
-  serialized_end=379,
+  serialized_start=342,
+  serialized_end=385,
 )
 
 
 _STARTUPLOADREQUEST = _descriptor.Descriptor(
   name='StartUploadRequest',
-  full_name='file.StartUploadRequest',
+  full_name='files.StartUploadRequest',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='upload', full_name='file.StartUploadRequest.upload', index=0,
+      name='upload', full_name='files.StartUploadRequest.upload', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -252,21 +252,21 @@ _STARTUPLOADREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=381,
-  serialized_end=440,
+  serialized_start=387,
+  serialized_end=447,
 )
 
 
 _STARTUPLOADRESPONSE = _descriptor.Descriptor(
   name='StartUploadResponse',
-  full_name='file.StartUploadResponse',
+  full_name='files.StartUploadResponse',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='upload', full_name='file.StartUploadResponse.upload', index=0,
+      name='upload', full_name='files.StartUploadResponse.upload', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -284,21 +284,21 @@ _STARTUPLOADRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=442,
-  serialized_end=502,
+  serialized_start=449,
+  serialized_end=510,
 )
 
 
 _COMPLETEUPLOADREQUEST = _descriptor.Descriptor(
   name='CompleteUploadRequest',
-  full_name='file.CompleteUploadRequest',
+  full_name='files.CompleteUploadRequest',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='upload', full_name='file.CompleteUploadRequest.upload', index=0,
+      name='upload', full_name='files.CompleteUploadRequest.upload', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -316,21 +316,21 @@ _COMPLETEUPLOADREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=504,
-  serialized_end=566,
+  serialized_start=512,
+  serialized_end=575,
 )
 
 
 _COMPLETEUPLOADRESPONSE = _descriptor.Descriptor(
   name='CompleteUploadResponse',
-  full_name='file.CompleteUploadResponse',
+  full_name='files.CompleteUploadResponse',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='upload', full_name='file.CompleteUploadResponse.upload', index=0,
+      name='upload', full_name='files.CompleteUploadResponse.upload', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -348,21 +348,21 @@ _COMPLETEUPLOADRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=568,
-  serialized_end=631,
+  serialized_start=577,
+  serialized_end=641,
 )
 
 
 _ABORTUPLOADREQUEST = _descriptor.Descriptor(
   name='AbortUploadRequest',
-  full_name='file.AbortUploadRequest',
+  full_name='files.AbortUploadRequest',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='upload', full_name='file.AbortUploadRequest.upload', index=0,
+      name='upload', full_name='files.AbortUploadRequest.upload', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -380,14 +380,14 @@ _ABORTUPLOADREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=633,
-  serialized_end=692,
+  serialized_start=643,
+  serialized_end=703,
 )
 
 
 _ABORTUPLOADRESPONSE = _descriptor.Descriptor(
   name='AbortUploadResponse',
-  full_name='file.AbortUploadResponse',
+  full_name='files.AbortUploadResponse',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
@@ -405,21 +405,21 @@ _ABORTUPLOADRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=694,
-  serialized_end=715,
+  serialized_start=705,
+  serialized_end=726,
 )
 
 
 _MOVEUPLOADREQUEST = _descriptor.Descriptor(
   name='MoveUploadRequest',
-  full_name='file.MoveUploadRequest',
+  full_name='files.MoveUploadRequest',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='upload', full_name='file.MoveUploadRequest.upload', index=0,
+      name='upload', full_name='files.MoveUploadRequest.upload', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -437,21 +437,21 @@ _MOVEUPLOADREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=717,
-  serialized_end=775,
+  serialized_start=728,
+  serialized_end=787,
 )
 
 
 _MOVEUPLOADRESPONSE = _descriptor.Descriptor(
   name='MoveUploadResponse',
-  full_name='file.MoveUploadResponse',
+  full_name='files.MoveUploadResponse',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='file', full_name='file.MoveUploadResponse.file', index=0,
+      name='file', full_name='files.MoveUploadResponse.file', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -469,21 +469,21 @@ _MOVEUPLOADRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=777,
-  serialized_end=823,
+  serialized_start=789,
+  serialized_end=836,
 )
 
 
 _UPLOADREQUEST = _descriptor.Descriptor(
   name='UploadRequest',
-  full_name='file.UploadRequest',
+  full_name='files.UploadRequest',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='file', full_name='file.UploadRequest.file', index=0,
+      name='file', full_name='files.UploadRequest.file', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -501,21 +501,21 @@ _UPLOADREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=825,
-  serialized_end=866,
+  serialized_start=838,
+  serialized_end=880,
 )
 
 
 _UPLOADRESPONSE = _descriptor.Descriptor(
   name='UploadResponse',
-  full_name='file.UploadResponse',
+  full_name='files.UploadResponse',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='upload', full_name='file.UploadResponse.upload', index=0,
+      name='upload', full_name='files.UploadResponse.upload', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -533,21 +533,21 @@ _UPLOADRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=868,
-  serialized_end=914,
+  serialized_start=882,
+  serialized_end=929,
 )
 
 
 _GETFILEREQUEST = _descriptor.Descriptor(
   name='GetFileRequest',
-  full_name='file.GetFileRequest',
+  full_name='files.GetFileRequest',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='id', full_name='file.GetFileRequest.id', index=0,
+      name='id', full_name='files.GetFileRequest.id', index=0,
       number=1, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
@@ -565,21 +565,21 @@ _GETFILEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=916,
-  serialized_end=944,
+  serialized_start=931,
+  serialized_end=959,
 )
 
 
 _GETFILERESPONSE = _descriptor.Descriptor(
   name='GetFileResponse',
-  full_name='file.GetFileResponse',
+  full_name='files.GetFileResponse',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='file', full_name='file.GetFileResponse.file', index=0,
+      name='file', full_name='files.GetFileResponse.file', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -597,21 +597,21 @@ _GETFILERESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=946,
-  serialized_end=989,
+  serialized_start=961,
+  serialized_end=1005,
 )
 
 
 _DELETEFILEREQUEST = _descriptor.Descriptor(
   name='DeleteFileRequest',
-  full_name='file.DeleteFileRequest',
+  full_name='files.DeleteFileRequest',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='file', full_name='file.DeleteFileRequest.file', index=0,
+      name='file', full_name='files.DeleteFileRequest.file', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -629,14 +629,14 @@ _DELETEFILEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=991,
-  serialized_end=1036,
+  serialized_start=1007,
+  serialized_end=1053,
 )
 
 
 _DELETEFILERESPONSE = _descriptor.Descriptor(
   name='DeleteFileResponse',
-  full_name='file.DeleteFileResponse',
+  full_name='files.DeleteFileResponse',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
@@ -654,8 +654,8 @@ _DELETEFILERESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1038,
-  serialized_end=1058,
+  serialized_start=1055,
+  serialized_end=1075,
 )
 
 _MULTIPARTUPLOAD.fields_by_name['file'].message_type = _FILE
@@ -694,146 +694,146 @@ _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
 File = _reflection.GeneratedProtocolMessageType('File', (_message.Message,), {
   'DESCRIPTOR' : _FILE,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.File)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.File)
   })
 _sym_db.RegisterMessage(File)
 
 MultipartUpload = _reflection.GeneratedProtocolMessageType('MultipartUpload', (_message.Message,), {
   'DESCRIPTOR' : _MULTIPARTUPLOAD,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.MultipartUpload)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.MultipartUpload)
   })
 _sym_db.RegisterMessage(MultipartUpload)
 
 Upload = _reflection.GeneratedProtocolMessageType('Upload', (_message.Message,), {
   'DESCRIPTOR' : _UPLOAD,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.Upload)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.Upload)
   })
 _sym_db.RegisterMessage(Upload)
 
 CompletedPart = _reflection.GeneratedProtocolMessageType('CompletedPart', (_message.Message,), {
   'DESCRIPTOR' : _COMPLETEDPART,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.CompletedPart)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.CompletedPart)
   })
 _sym_db.RegisterMessage(CompletedPart)
 
 StartUploadRequest = _reflection.GeneratedProtocolMessageType('StartUploadRequest', (_message.Message,), {
   'DESCRIPTOR' : _STARTUPLOADREQUEST,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.StartUploadRequest)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.StartUploadRequest)
   })
 _sym_db.RegisterMessage(StartUploadRequest)
 
 StartUploadResponse = _reflection.GeneratedProtocolMessageType('StartUploadResponse', (_message.Message,), {
   'DESCRIPTOR' : _STARTUPLOADRESPONSE,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.StartUploadResponse)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.StartUploadResponse)
   })
 _sym_db.RegisterMessage(StartUploadResponse)
 
 CompleteUploadRequest = _reflection.GeneratedProtocolMessageType('CompleteUploadRequest', (_message.Message,), {
   'DESCRIPTOR' : _COMPLETEUPLOADREQUEST,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.CompleteUploadRequest)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.CompleteUploadRequest)
   })
 _sym_db.RegisterMessage(CompleteUploadRequest)
 
 CompleteUploadResponse = _reflection.GeneratedProtocolMessageType('CompleteUploadResponse', (_message.Message,), {
   'DESCRIPTOR' : _COMPLETEUPLOADRESPONSE,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.CompleteUploadResponse)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.CompleteUploadResponse)
   })
 _sym_db.RegisterMessage(CompleteUploadResponse)
 
 AbortUploadRequest = _reflection.GeneratedProtocolMessageType('AbortUploadRequest', (_message.Message,), {
   'DESCRIPTOR' : _ABORTUPLOADREQUEST,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.AbortUploadRequest)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.AbortUploadRequest)
   })
 _sym_db.RegisterMessage(AbortUploadRequest)
 
 AbortUploadResponse = _reflection.GeneratedProtocolMessageType('AbortUploadResponse', (_message.Message,), {
   'DESCRIPTOR' : _ABORTUPLOADRESPONSE,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.AbortUploadResponse)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.AbortUploadResponse)
   })
 _sym_db.RegisterMessage(AbortUploadResponse)
 
 MoveUploadRequest = _reflection.GeneratedProtocolMessageType('MoveUploadRequest', (_message.Message,), {
   'DESCRIPTOR' : _MOVEUPLOADREQUEST,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.MoveUploadRequest)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.MoveUploadRequest)
   })
 _sym_db.RegisterMessage(MoveUploadRequest)
 
 MoveUploadResponse = _reflection.GeneratedProtocolMessageType('MoveUploadResponse', (_message.Message,), {
   'DESCRIPTOR' : _MOVEUPLOADRESPONSE,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.MoveUploadResponse)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.MoveUploadResponse)
   })
 _sym_db.RegisterMessage(MoveUploadResponse)
 
 UploadRequest = _reflection.GeneratedProtocolMessageType('UploadRequest', (_message.Message,), {
   'DESCRIPTOR' : _UPLOADREQUEST,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.UploadRequest)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.UploadRequest)
   })
 _sym_db.RegisterMessage(UploadRequest)
 
 UploadResponse = _reflection.GeneratedProtocolMessageType('UploadResponse', (_message.Message,), {
   'DESCRIPTOR' : _UPLOADRESPONSE,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.UploadResponse)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.UploadResponse)
   })
 _sym_db.RegisterMessage(UploadResponse)
 
 GetFileRequest = _reflection.GeneratedProtocolMessageType('GetFileRequest', (_message.Message,), {
   'DESCRIPTOR' : _GETFILEREQUEST,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.GetFileRequest)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.GetFileRequest)
   })
 _sym_db.RegisterMessage(GetFileRequest)
 
 GetFileResponse = _reflection.GeneratedProtocolMessageType('GetFileResponse', (_message.Message,), {
   'DESCRIPTOR' : _GETFILERESPONSE,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.GetFileResponse)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.GetFileResponse)
   })
 _sym_db.RegisterMessage(GetFileResponse)
 
 DeleteFileRequest = _reflection.GeneratedProtocolMessageType('DeleteFileRequest', (_message.Message,), {
   'DESCRIPTOR' : _DELETEFILEREQUEST,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.DeleteFileRequest)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.DeleteFileRequest)
   })
 _sym_db.RegisterMessage(DeleteFileRequest)
 
 DeleteFileResponse = _reflection.GeneratedProtocolMessageType('DeleteFileResponse', (_message.Message,), {
   'DESCRIPTOR' : _DELETEFILERESPONSE,
-  '__module__' : 'perxis.file.file_pb2'
-  # @@protoc_insertion_point(class_scope:file.DeleteFileResponse)
+  '__module__' : 'perxis.files.files_pb2'
+  # @@protoc_insertion_point(class_scope:files.DeleteFileResponse)
   })
 _sym_db.RegisterMessage(DeleteFileResponse)
 
 
 DESCRIPTOR._options = None
 
-_FILESERVICE = _descriptor.ServiceDescriptor(
-  name='FileService',
-  full_name='file.FileService',
+_FILES = _descriptor.ServiceDescriptor(
+  name='Files',
+  full_name='files.Files',
   file=DESCRIPTOR,
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=1061,
-  serialized_end=1535,
+  serialized_start=1078,
+  serialized_end=1558,
   methods=[
   _descriptor.MethodDescriptor(
     name='StartUpload',
-    full_name='file.FileService.StartUpload',
+    full_name='files.Files.StartUpload',
     index=0,
     containing_service=None,
     input_type=_STARTUPLOADREQUEST,
@@ -843,7 +843,7 @@ _FILESERVICE = _descriptor.ServiceDescriptor(
   ),
   _descriptor.MethodDescriptor(
     name='CompleteUpload',
-    full_name='file.FileService.CompleteUpload',
+    full_name='files.Files.CompleteUpload',
     index=1,
     containing_service=None,
     input_type=_COMPLETEUPLOADREQUEST,
@@ -853,7 +853,7 @@ _FILESERVICE = _descriptor.ServiceDescriptor(
   ),
   _descriptor.MethodDescriptor(
     name='AbortUpload',
-    full_name='file.FileService.AbortUpload',
+    full_name='files.Files.AbortUpload',
     index=2,
     containing_service=None,
     input_type=_ABORTUPLOADREQUEST,
@@ -863,7 +863,7 @@ _FILESERVICE = _descriptor.ServiceDescriptor(
   ),
   _descriptor.MethodDescriptor(
     name='MoveUpload',
-    full_name='file.FileService.MoveUpload',
+    full_name='files.Files.MoveUpload',
     index=3,
     containing_service=None,
     input_type=_MOVEUPLOADREQUEST,
@@ -873,7 +873,7 @@ _FILESERVICE = _descriptor.ServiceDescriptor(
   ),
   _descriptor.MethodDescriptor(
     name='Upload',
-    full_name='file.FileService.Upload',
+    full_name='files.Files.Upload',
     index=4,
     containing_service=None,
     input_type=_UPLOADREQUEST,
@@ -883,7 +883,7 @@ _FILESERVICE = _descriptor.ServiceDescriptor(
   ),
   _descriptor.MethodDescriptor(
     name='GetFile',
-    full_name='file.FileService.GetFile',
+    full_name='files.Files.GetFile',
     index=5,
     containing_service=None,
     input_type=_GETFILEREQUEST,
@@ -893,7 +893,7 @@ _FILESERVICE = _descriptor.ServiceDescriptor(
   ),
   _descriptor.MethodDescriptor(
     name='DeleteFile',
-    full_name='file.FileService.DeleteFile',
+    full_name='files.Files.DeleteFile',
     index=6,
     containing_service=None,
     input_type=_DELETEFILEREQUEST,
@@ -902,8 +902,8 @@ _FILESERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
 ])
-_sym_db.RegisterServiceDescriptor(_FILESERVICE)
+_sym_db.RegisterServiceDescriptor(_FILES)
 
-DESCRIPTOR.services_by_name['FileService'] = _FILESERVICE
+DESCRIPTOR.services_by_name['Files'] = _FILES
 
 # @@protoc_insertion_point(module_scope)
diff --git a/perxis/file/file_pb2_grpc.py b/perxis/files/files_pb2_grpc.py
similarity index 69%
rename from perxis/file/file_pb2_grpc.py
rename to perxis/files/files_pb2_grpc.py
index 4798fd96d7e4125de1f8194fd6fb38eadca7492d..1f2b109bd8f136b101e71fdf569db83e2a4fd642 100644
--- a/perxis/file/file_pb2_grpc.py
+++ b/perxis/files/files_pb2_grpc.py
@@ -3,10 +3,10 @@
 import grpc
 
 from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
-from perxis.file import file_pb2 as perxis_dot_file_dot_file__pb2
+from perxis.files import files_pb2 as perxis_dot_files_dot_files__pb2
 
 
-class FileServiceStub(object):
+class FilesStub(object):
     """Missing associated documentation comment in .proto file."""
 
     def __init__(self, channel):
@@ -16,43 +16,43 @@ class FileServiceStub(object):
             channel: A grpc.Channel.
         """
         self.StartUpload = channel.unary_unary(
-                '/file.FileService/StartUpload',
-                request_serializer=perxis_dot_file_dot_file__pb2.StartUploadRequest.SerializeToString,
-                response_deserializer=perxis_dot_file_dot_file__pb2.StartUploadResponse.FromString,
+                '/files.Files/StartUpload',
+                request_serializer=perxis_dot_files_dot_files__pb2.StartUploadRequest.SerializeToString,
+                response_deserializer=perxis_dot_files_dot_files__pb2.StartUploadResponse.FromString,
                 )
         self.CompleteUpload = channel.unary_unary(
-                '/file.FileService/CompleteUpload',
-                request_serializer=perxis_dot_file_dot_file__pb2.CompleteUploadRequest.SerializeToString,
-                response_deserializer=perxis_dot_file_dot_file__pb2.CompleteUploadResponse.FromString,
+                '/files.Files/CompleteUpload',
+                request_serializer=perxis_dot_files_dot_files__pb2.CompleteUploadRequest.SerializeToString,
+                response_deserializer=perxis_dot_files_dot_files__pb2.CompleteUploadResponse.FromString,
                 )
         self.AbortUpload = channel.unary_unary(
-                '/file.FileService/AbortUpload',
-                request_serializer=perxis_dot_file_dot_file__pb2.AbortUploadRequest.SerializeToString,
+                '/files.Files/AbortUpload',
+                request_serializer=perxis_dot_files_dot_files__pb2.AbortUploadRequest.SerializeToString,
                 response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
                 )
         self.MoveUpload = channel.unary_unary(
-                '/file.FileService/MoveUpload',
-                request_serializer=perxis_dot_file_dot_file__pb2.MoveUploadRequest.SerializeToString,
-                response_deserializer=perxis_dot_file_dot_file__pb2.MoveUploadResponse.FromString,
+                '/files.Files/MoveUpload',
+                request_serializer=perxis_dot_files_dot_files__pb2.MoveUploadRequest.SerializeToString,
+                response_deserializer=perxis_dot_files_dot_files__pb2.MoveUploadResponse.FromString,
                 )
         self.Upload = channel.unary_unary(
-                '/file.FileService/Upload',
-                request_serializer=perxis_dot_file_dot_file__pb2.UploadRequest.SerializeToString,
-                response_deserializer=perxis_dot_file_dot_file__pb2.UploadResponse.FromString,
+                '/files.Files/Upload',
+                request_serializer=perxis_dot_files_dot_files__pb2.UploadRequest.SerializeToString,
+                response_deserializer=perxis_dot_files_dot_files__pb2.UploadResponse.FromString,
                 )
         self.GetFile = channel.unary_unary(
-                '/file.FileService/GetFile',
-                request_serializer=perxis_dot_file_dot_file__pb2.GetFileRequest.SerializeToString,
-                response_deserializer=perxis_dot_file_dot_file__pb2.GetFileResponse.FromString,
+                '/files.Files/GetFile',
+                request_serializer=perxis_dot_files_dot_files__pb2.GetFileRequest.SerializeToString,
+                response_deserializer=perxis_dot_files_dot_files__pb2.GetFileResponse.FromString,
                 )
         self.DeleteFile = channel.unary_unary(
-                '/file.FileService/DeleteFile',
-                request_serializer=perxis_dot_file_dot_file__pb2.DeleteFileRequest.SerializeToString,
+                '/files.Files/DeleteFile',
+                request_serializer=perxis_dot_files_dot_files__pb2.DeleteFileRequest.SerializeToString,
                 response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString,
                 )
 
 
-class FileServiceServicer(object):
+class FilesServicer(object):
     """Missing associated documentation comment in .proto file."""
 
     def StartUpload(self, request, context):
@@ -113,51 +113,51 @@ class FileServiceServicer(object):
         raise NotImplementedError('Method not implemented!')
 
 
-def add_FileServiceServicer_to_server(servicer, server):
+def add_FilesServicer_to_server(servicer, server):
     rpc_method_handlers = {
             'StartUpload': grpc.unary_unary_rpc_method_handler(
                     servicer.StartUpload,
-                    request_deserializer=perxis_dot_file_dot_file__pb2.StartUploadRequest.FromString,
-                    response_serializer=perxis_dot_file_dot_file__pb2.StartUploadResponse.SerializeToString,
+                    request_deserializer=perxis_dot_files_dot_files__pb2.StartUploadRequest.FromString,
+                    response_serializer=perxis_dot_files_dot_files__pb2.StartUploadResponse.SerializeToString,
             ),
             'CompleteUpload': grpc.unary_unary_rpc_method_handler(
                     servicer.CompleteUpload,
-                    request_deserializer=perxis_dot_file_dot_file__pb2.CompleteUploadRequest.FromString,
-                    response_serializer=perxis_dot_file_dot_file__pb2.CompleteUploadResponse.SerializeToString,
+                    request_deserializer=perxis_dot_files_dot_files__pb2.CompleteUploadRequest.FromString,
+                    response_serializer=perxis_dot_files_dot_files__pb2.CompleteUploadResponse.SerializeToString,
             ),
             'AbortUpload': grpc.unary_unary_rpc_method_handler(
                     servicer.AbortUpload,
-                    request_deserializer=perxis_dot_file_dot_file__pb2.AbortUploadRequest.FromString,
+                    request_deserializer=perxis_dot_files_dot_files__pb2.AbortUploadRequest.FromString,
                     response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
             ),
             'MoveUpload': grpc.unary_unary_rpc_method_handler(
                     servicer.MoveUpload,
-                    request_deserializer=perxis_dot_file_dot_file__pb2.MoveUploadRequest.FromString,
-                    response_serializer=perxis_dot_file_dot_file__pb2.MoveUploadResponse.SerializeToString,
+                    request_deserializer=perxis_dot_files_dot_files__pb2.MoveUploadRequest.FromString,
+                    response_serializer=perxis_dot_files_dot_files__pb2.MoveUploadResponse.SerializeToString,
             ),
             'Upload': grpc.unary_unary_rpc_method_handler(
                     servicer.Upload,
-                    request_deserializer=perxis_dot_file_dot_file__pb2.UploadRequest.FromString,
-                    response_serializer=perxis_dot_file_dot_file__pb2.UploadResponse.SerializeToString,
+                    request_deserializer=perxis_dot_files_dot_files__pb2.UploadRequest.FromString,
+                    response_serializer=perxis_dot_files_dot_files__pb2.UploadResponse.SerializeToString,
             ),
             'GetFile': grpc.unary_unary_rpc_method_handler(
                     servicer.GetFile,
-                    request_deserializer=perxis_dot_file_dot_file__pb2.GetFileRequest.FromString,
-                    response_serializer=perxis_dot_file_dot_file__pb2.GetFileResponse.SerializeToString,
+                    request_deserializer=perxis_dot_files_dot_files__pb2.GetFileRequest.FromString,
+                    response_serializer=perxis_dot_files_dot_files__pb2.GetFileResponse.SerializeToString,
             ),
             'DeleteFile': grpc.unary_unary_rpc_method_handler(
                     servicer.DeleteFile,
-                    request_deserializer=perxis_dot_file_dot_file__pb2.DeleteFileRequest.FromString,
+                    request_deserializer=perxis_dot_files_dot_files__pb2.DeleteFileRequest.FromString,
                     response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString,
             ),
     }
     generic_handler = grpc.method_handlers_generic_handler(
-            'file.FileService', rpc_method_handlers)
+            'files.Files', rpc_method_handlers)
     server.add_generic_rpc_handlers((generic_handler,))
 
 
  # This class is part of an EXPERIMENTAL API.
-class FileService(object):
+class Files(object):
     """Missing associated documentation comment in .proto file."""
 
     @staticmethod
@@ -171,9 +171,9 @@ class FileService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/file.FileService/StartUpload',
-            perxis_dot_file_dot_file__pb2.StartUploadRequest.SerializeToString,
-            perxis_dot_file_dot_file__pb2.StartUploadResponse.FromString,
+        return grpc.experimental.unary_unary(request, target, '/files.Files/StartUpload',
+            perxis_dot_files_dot_files__pb2.StartUploadRequest.SerializeToString,
+            perxis_dot_files_dot_files__pb2.StartUploadResponse.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
@@ -188,9 +188,9 @@ class FileService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/file.FileService/CompleteUpload',
-            perxis_dot_file_dot_file__pb2.CompleteUploadRequest.SerializeToString,
-            perxis_dot_file_dot_file__pb2.CompleteUploadResponse.FromString,
+        return grpc.experimental.unary_unary(request, target, '/files.Files/CompleteUpload',
+            perxis_dot_files_dot_files__pb2.CompleteUploadRequest.SerializeToString,
+            perxis_dot_files_dot_files__pb2.CompleteUploadResponse.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
@@ -205,8 +205,8 @@ class FileService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/file.FileService/AbortUpload',
-            perxis_dot_file_dot_file__pb2.AbortUploadRequest.SerializeToString,
+        return grpc.experimental.unary_unary(request, target, '/files.Files/AbortUpload',
+            perxis_dot_files_dot_files__pb2.AbortUploadRequest.SerializeToString,
             google_dot_protobuf_dot_empty__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@@ -222,9 +222,9 @@ class FileService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/file.FileService/MoveUpload',
-            perxis_dot_file_dot_file__pb2.MoveUploadRequest.SerializeToString,
-            perxis_dot_file_dot_file__pb2.MoveUploadResponse.FromString,
+        return grpc.experimental.unary_unary(request, target, '/files.Files/MoveUpload',
+            perxis_dot_files_dot_files__pb2.MoveUploadRequest.SerializeToString,
+            perxis_dot_files_dot_files__pb2.MoveUploadResponse.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
@@ -239,9 +239,9 @@ class FileService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/file.FileService/Upload',
-            perxis_dot_file_dot_file__pb2.UploadRequest.SerializeToString,
-            perxis_dot_file_dot_file__pb2.UploadResponse.FromString,
+        return grpc.experimental.unary_unary(request, target, '/files.Files/Upload',
+            perxis_dot_files_dot_files__pb2.UploadRequest.SerializeToString,
+            perxis_dot_files_dot_files__pb2.UploadResponse.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
@@ -256,9 +256,9 @@ class FileService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/file.FileService/GetFile',
-            perxis_dot_file_dot_file__pb2.GetFileRequest.SerializeToString,
-            perxis_dot_file_dot_file__pb2.GetFileResponse.FromString,
+        return grpc.experimental.unary_unary(request, target, '/files.Files/GetFile',
+            perxis_dot_files_dot_files__pb2.GetFileRequest.SerializeToString,
+            perxis_dot_files_dot_files__pb2.GetFileResponse.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
@@ -273,8 +273,8 @@ class FileService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/file.FileService/DeleteFile',
-            perxis_dot_file_dot_file__pb2.DeleteFileRequest.SerializeToString,
+        return grpc.experimental.unary_unary(request, target, '/files.Files/DeleteFile',
+            perxis_dot_files_dot_files__pb2.DeleteFileRequest.SerializeToString,
             google_dot_protobuf_dot_empty__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/perxis/images/__init__.py b/perxis/images/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/perxis/image/image_pb2.py b/perxis/images/images_pb2.py
similarity index 70%
rename from perxis/image/image_pb2.py
rename to perxis/images/images_pb2.py
index 9a79e731f51464b1d170ac2e1c0f5e32cf2aef4e..032522c1314558bb61b3859003ddee94664bbf10 100644
--- a/perxis/image/image_pb2.py
+++ b/perxis/images/images_pb2.py
@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
-# source: perxis/image/image.proto
+# source: perxis/images/images.proto
 """Generated protocol buffer code."""
 from google.protobuf import descriptor as _descriptor
 from google.protobuf import message as _message
@@ -11,39 +11,39 @@ from google.protobuf import symbol_database as _symbol_database
 _sym_db = _symbol_database.Default()
 
 
-from perxis.file import file_pb2 as perxis_dot_file_dot_file__pb2
+from perxis.files import files_pb2 as perxis_dot_files_dot_files__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
-  name='perxis/image/image.proto',
-  package='image',
+  name='perxis/images/images.proto',
+  package='images',
   syntax='proto3',
-  serialized_options=b'Z,github.com/perxteam/perxis/proto/image;image',
+  serialized_options=b'Z.github.com/perxteam/perxis/proto/images;images',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x18perxis/image/image.proto\x12\x05image\x1a\x16perxis/file/file.proto\"\"\n\x05Param\x12\n\n\x02op\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x03(\t\"\x80\x01\n\nGetRequest\x12\x1a\n\x06source\x18\x01 \x01(\x0b\x32\n.file.File\x12*\n\x04opts\x18\x02 \x01(\x0b\x32\x1c.image.GetRequest.GetOptions\x1a*\n\nGetOptions\x12\x1c\n\x06params\x18\x01 \x03(\x0b\x32\x0c.image.Param\")\n\x0bGetResponse\x12\x1a\n\x06result\x18\x01 \x01(\x0b\x32\n.file.File2>\n\x0cImageService\x12.\n\x03Get\x12\x11.image.GetRequest\x1a\x12.image.GetResponse\"\x00\x42.Z,github.com/perxteam/perxis/proto/image;imageb\x06proto3'
+  serialized_pb=b'\n\x1aperxis/images/images.proto\x12\x06images\x1a\x18perxis/files/files.proto\"\"\n\x05Param\x12\n\n\x02op\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x03(\t\"\x83\x01\n\nGetRequest\x12\x1b\n\x06source\x18\x01 \x01(\x0b\x32\x0b.files.File\x12+\n\x04opts\x18\x02 \x01(\x0b\x32\x1d.images.GetRequest.GetOptions\x1a+\n\nGetOptions\x12\x1d\n\x06params\x18\x01 \x03(\x0b\x32\r.images.Param\"*\n\x0bGetResponse\x12\x1b\n\x06result\x18\x01 \x01(\x0b\x32\x0b.files.File2:\n\x06Images\x12\x30\n\x03Get\x12\x12.images.GetRequest\x1a\x13.images.GetResponse\"\x00\x42\x30Z.github.com/perxteam/perxis/proto/images;imagesb\x06proto3'
   ,
-  dependencies=[perxis_dot_file_dot_file__pb2.DESCRIPTOR,])
+  dependencies=[perxis_dot_files_dot_files__pb2.DESCRIPTOR,])
 
 
 
 
 _PARAM = _descriptor.Descriptor(
   name='Param',
-  full_name='image.Param',
+  full_name='images.Param',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='op', full_name='image.Param.op', index=0,
+      name='op', full_name='images.Param.op', index=0,
       number=1, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='value', full_name='image.Param.value', index=1,
+      name='value', full_name='images.Param.value', index=1,
       number=2, type=9, cpp_type=9, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
@@ -61,21 +61,21 @@ _PARAM = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=59,
-  serialized_end=93,
+  serialized_start=64,
+  serialized_end=98,
 )
 
 
 _GETREQUEST_GETOPTIONS = _descriptor.Descriptor(
   name='GetOptions',
-  full_name='image.GetRequest.GetOptions',
+  full_name='images.GetRequest.GetOptions',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='params', full_name='image.GetRequest.GetOptions.params', index=0,
+      name='params', full_name='images.GetRequest.GetOptions.params', index=0,
       number=1, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
@@ -93,27 +93,27 @@ _GETREQUEST_GETOPTIONS = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=182,
-  serialized_end=224,
+  serialized_start=189,
+  serialized_end=232,
 )
 
 _GETREQUEST = _descriptor.Descriptor(
   name='GetRequest',
-  full_name='image.GetRequest',
+  full_name='images.GetRequest',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='source', full_name='image.GetRequest.source', index=0,
+      name='source', full_name='images.GetRequest.source', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='opts', full_name='image.GetRequest.opts', index=1,
+      name='opts', full_name='images.GetRequest.opts', index=1,
       number=2, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -131,21 +131,21 @@ _GETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=96,
-  serialized_end=224,
+  serialized_start=101,
+  serialized_end=232,
 )
 
 
 _GETRESPONSE = _descriptor.Descriptor(
   name='GetResponse',
-  full_name='image.GetResponse',
+  full_name='images.GetResponse',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='result', full_name='image.GetResponse.result', index=0,
+      name='result', full_name='images.GetResponse.result', index=0,
       number=1, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -163,15 +163,15 @@ _GETRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=226,
-  serialized_end=267,
+  serialized_start=234,
+  serialized_end=276,
 )
 
 _GETREQUEST_GETOPTIONS.fields_by_name['params'].message_type = _PARAM
 _GETREQUEST_GETOPTIONS.containing_type = _GETREQUEST
-_GETREQUEST.fields_by_name['source'].message_type = perxis_dot_file_dot_file__pb2._FILE
+_GETREQUEST.fields_by_name['source'].message_type = perxis_dot_files_dot_files__pb2._FILE
 _GETREQUEST.fields_by_name['opts'].message_type = _GETREQUEST_GETOPTIONS
-_GETRESPONSE.fields_by_name['result'].message_type = perxis_dot_file_dot_file__pb2._FILE
+_GETRESPONSE.fields_by_name['result'].message_type = perxis_dot_files_dot_files__pb2._FILE
 DESCRIPTOR.message_types_by_name['Param'] = _PARAM
 DESCRIPTOR.message_types_by_name['GetRequest'] = _GETREQUEST
 DESCRIPTOR.message_types_by_name['GetResponse'] = _GETRESPONSE
@@ -179,8 +179,8 @@ _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
 Param = _reflection.GeneratedProtocolMessageType('Param', (_message.Message,), {
   'DESCRIPTOR' : _PARAM,
-  '__module__' : 'perxis.image.image_pb2'
-  # @@protoc_insertion_point(class_scope:image.Param)
+  '__module__' : 'perxis.images.images_pb2'
+  # @@protoc_insertion_point(class_scope:images.Param)
   })
 _sym_db.RegisterMessage(Param)
 
@@ -188,40 +188,40 @@ GetRequest = _reflection.GeneratedProtocolMessageType('GetRequest', (_message.Me
 
   'GetOptions' : _reflection.GeneratedProtocolMessageType('GetOptions', (_message.Message,), {
     'DESCRIPTOR' : _GETREQUEST_GETOPTIONS,
-    '__module__' : 'perxis.image.image_pb2'
-    # @@protoc_insertion_point(class_scope:image.GetRequest.GetOptions)
+    '__module__' : 'perxis.images.images_pb2'
+    # @@protoc_insertion_point(class_scope:images.GetRequest.GetOptions)
     })
   ,
   'DESCRIPTOR' : _GETREQUEST,
-  '__module__' : 'perxis.image.image_pb2'
-  # @@protoc_insertion_point(class_scope:image.GetRequest)
+  '__module__' : 'perxis.images.images_pb2'
+  # @@protoc_insertion_point(class_scope:images.GetRequest)
   })
 _sym_db.RegisterMessage(GetRequest)
 _sym_db.RegisterMessage(GetRequest.GetOptions)
 
 GetResponse = _reflection.GeneratedProtocolMessageType('GetResponse', (_message.Message,), {
   'DESCRIPTOR' : _GETRESPONSE,
-  '__module__' : 'perxis.image.image_pb2'
-  # @@protoc_insertion_point(class_scope:image.GetResponse)
+  '__module__' : 'perxis.images.images_pb2'
+  # @@protoc_insertion_point(class_scope:images.GetResponse)
   })
 _sym_db.RegisterMessage(GetResponse)
 
 
 DESCRIPTOR._options = None
 
-_IMAGESERVICE = _descriptor.ServiceDescriptor(
-  name='ImageService',
-  full_name='image.ImageService',
+_IMAGES = _descriptor.ServiceDescriptor(
+  name='Images',
+  full_name='images.Images',
   file=DESCRIPTOR,
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=269,
-  serialized_end=331,
+  serialized_start=278,
+  serialized_end=336,
   methods=[
   _descriptor.MethodDescriptor(
     name='Get',
-    full_name='image.ImageService.Get',
+    full_name='images.Images.Get',
     index=0,
     containing_service=None,
     input_type=_GETREQUEST,
@@ -230,8 +230,8 @@ _IMAGESERVICE = _descriptor.ServiceDescriptor(
     create_key=_descriptor._internal_create_key,
   ),
 ])
-_sym_db.RegisterServiceDescriptor(_IMAGESERVICE)
+_sym_db.RegisterServiceDescriptor(_IMAGES)
 
-DESCRIPTOR.services_by_name['ImageService'] = _IMAGESERVICE
+DESCRIPTOR.services_by_name['Images'] = _IMAGES
 
 # @@protoc_insertion_point(module_scope)
diff --git a/perxis/image/image_pb2_grpc.py b/perxis/images/images_pb2_grpc.py
similarity index 72%
rename from perxis/image/image_pb2_grpc.py
rename to perxis/images/images_pb2_grpc.py
index d5a7e66725d80077cc620bbc3f810cccc0defef3..5b19b312e53cc4e320b5c0413e94a4f7193fa21c 100644
--- a/perxis/image/image_pb2_grpc.py
+++ b/perxis/images/images_pb2_grpc.py
@@ -2,10 +2,10 @@
 """Client and server classes corresponding to protobuf-defined services."""
 import grpc
 
-from perxis.image import image_pb2 as perxis_dot_image_dot_image__pb2
+from perxis.images import images_pb2 as perxis_dot_images_dot_images__pb2
 
 
-class ImageServiceStub(object):
+class ImagesStub(object):
     """ImageService - сервис для обработки изображений
     """
 
@@ -16,13 +16,13 @@ class ImageServiceStub(object):
             channel: A grpc.Channel.
         """
         self.Get = channel.unary_unary(
-                '/image.ImageService/Get',
-                request_serializer=perxis_dot_image_dot_image__pb2.GetRequest.SerializeToString,
-                response_deserializer=perxis_dot_image_dot_image__pb2.GetResponse.FromString,
+                '/images.Images/Get',
+                request_serializer=perxis_dot_images_dot_images__pb2.GetRequest.SerializeToString,
+                response_deserializer=perxis_dot_images_dot_images__pb2.GetResponse.FromString,
                 )
 
 
-class ImageServiceServicer(object):
+class ImagesServicer(object):
     """ImageService - сервис для обработки изображений
     """
 
@@ -41,21 +41,21 @@ class ImageServiceServicer(object):
         raise NotImplementedError('Method not implemented!')
 
 
-def add_ImageServiceServicer_to_server(servicer, server):
+def add_ImagesServicer_to_server(servicer, server):
     rpc_method_handlers = {
             'Get': grpc.unary_unary_rpc_method_handler(
                     servicer.Get,
-                    request_deserializer=perxis_dot_image_dot_image__pb2.GetRequest.FromString,
-                    response_serializer=perxis_dot_image_dot_image__pb2.GetResponse.SerializeToString,
+                    request_deserializer=perxis_dot_images_dot_images__pb2.GetRequest.FromString,
+                    response_serializer=perxis_dot_images_dot_images__pb2.GetResponse.SerializeToString,
             ),
     }
     generic_handler = grpc.method_handlers_generic_handler(
-            'image.ImageService', rpc_method_handlers)
+            'images.Images', rpc_method_handlers)
     server.add_generic_rpc_handlers((generic_handler,))
 
 
  # This class is part of an EXPERIMENTAL API.
-class ImageService(object):
+class Images(object):
     """ImageService - сервис для обработки изображений
     """
 
@@ -70,8 +70,8 @@ class ImageService(object):
             wait_for_ready=None,
             timeout=None,
             metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/image.ImageService/Get',
-            perxis_dot_image_dot_image__pb2.GetRequest.SerializeToString,
-            perxis_dot_image_dot_image__pb2.GetResponse.FromString,
+        return grpc.experimental.unary_unary(request, target, '/images.Images/Get',
+            perxis_dot_images_dot_images__pb2.GetRequest.SerializeToString,
+            perxis_dot_images_dot_images__pb2.GetResponse.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/perxis/items/items_pb2.py b/perxis/items/items_pb2.py
index 0b51318112a146db8c5b640e3a7409c9d7166d61..59ec728cc96c602b775e29f02de8348206f59ba4 100644
--- a/perxis/items/items_pb2.py
+++ b/perxis/items/items_pb2.py
@@ -23,7 +23,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z,github.com/perxteam/perxis/proto/items;items',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x18perxis/items/items.proto\x12\rcontent.items\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1aperxis/common/common.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\"\'\n\x05\x45rror\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\r\n\x05\x66ield\x18\x02 \x01(\t\"3\n\x0b\x44\x65\x63odeError\x12$\n\x06\x65rrors\x18\x02 \x03(\x0b\x32\x14.content.items.Error\"7\n\x0fValidationError\x12$\n\x06\x65rrors\x18\x02 \x03(\x0b\x32\x14.content.items.Error\"9\n\x11ModificationError\x12$\n\x06\x65rrors\x18\x02 \x03(\x0b\x32\x14.content.items.Error\"\xcc\x04\n\x04Item\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x03 \x01(\t\x12\x15\n\rcollection_id\x18\x04 \x01(\t\x12(\n\x05state\x18\x05 \x01(\x0e\x32\x19.content.items.Item.State\x12.\n\ncreated_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\ncreated_by\x18\x07 \x01(\t\x12%\n\x04\x64\x61ta\x18\x08 \x01(\x0b\x32\x17.google.protobuf.Struct\x12;\n\x0ctranslations\x18\t \x03(\x0b\x32%.content.items.Item.TranslationsEntry\x12\x13\n\x0brevision_id\x18\n \x01(\t\x12\x30\n\x0cpublished_at\x18\x0b \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x14\n\x0cpublished_by\x18\x0c \x01(\t\x12/\n\x0b\x61rchived_at\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0b\x61rchived_by\x18\x0e \x01(\t\x1aL\n\x11TranslationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct:\x02\x38\x01\"<\n\x05State\x12\t\n\x05\x44RAFT\x10\x00\x12\r\n\tPUBLISHED\x10\x01\x12\x0b\n\x07\x43HANGED\x10\x02\x12\x0c\n\x08\x41RCHIVED\x10\x03\"2\n\x06\x46ilter\x12\n\n\x02id\x18\x01 \x03(\t\x12\x1c\n\x04\x64\x61ta\x18\x02 \x03(\x0b\x32\x0e.common.Filter\"2\n\rCreateRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"6\n\x0e\x43reateResponse\x12$\n\x07\x63reated\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"V\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"0\n\x0bGetResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\x93\x01\n\x0b\x46indRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12%\n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x15.content.items.Filter\x12$\n\x07options\x18\x05 \x01(\x0b\x32\x13.common.FindOptions\"A\n\x0c\x46indResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\x12\r\n\x05total\x18\x02 \x01(\x05\"2\n\rUpdateRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"Y\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"3\n\x0ePublishRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\\\n\x10UnpublishRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"r\n\x13GetPublishedRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x11\n\tlocale_id\x18\x04 \x01(\t\x12\x0f\n\x07item_id\x18\x05 \x01(\t\"9\n\x14GetPublishedResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\xaf\x01\n\x14\x46indPublishedRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x11\n\tlocale_id\x18\x04 \x01(\t\x12%\n\x06\x66ilter\x18\x05 \x01(\x0b\x32\x15.content.items.Filter\x12$\n\x07options\x18\x06 \x01(\x0b\x32\x13.common.FindOptions\"J\n\x15\x46indPublishedResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\x12\r\n\x05total\x18\x02 \x01(\x05\"s\n\x12GetRevisionRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\x12\x13\n\x0brevision_id\x18\x05 \x01(\t\"8\n\x13GetRevisionResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"`\n\x14ListRevisionsRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\";\n\x15ListRevisionsResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\"3\n\x0e\x41rchiveRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\\\n\x10UnarchiveRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"\x9b\x01\n\x13\x46indArchivedRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12%\n\x06\x66ilter\x18\x05 \x01(\x0b\x32\x15.content.items.Filter\x12$\n\x07options\x18\x06 \x01(\x0b\x32\x13.common.FindOptions\"I\n\x14\x46indArchivedResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\x12\r\n\x05total\x18\x02 \x01(\x05\x32\xb9\x08\n\x05Items\x12G\n\x06\x43reate\x12\x1c.content.items.CreateRequest\x1a\x1d.content.items.CreateResponse\"\x00\x12>\n\x03Get\x12\x19.content.items.GetRequest\x1a\x1a.content.items.GetResponse\"\x00\x12\x41\n\x04\x46ind\x12\x1a.content.items.FindRequest\x1a\x1b.content.items.FindResponse\"\x00\x12@\n\x06Update\x12\x1c.content.items.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12@\n\x06\x44\x65lete\x12\x1c.content.items.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x42\n\x07Publish\x12\x1d.content.items.PublishRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\tUnpublish\x12\x1f.content.items.UnpublishRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Y\n\x0cGetPublished\x12\".content.items.GetPublishedRequest\x1a#.content.items.GetPublishedResponse\"\x00\x12\\\n\rFindPublished\x12#.content.items.FindPublishedRequest\x1a$.content.items.FindPublishedResponse\"\x00\x12V\n\x0bGetRevision\x12!.content.items.GetRevisionRequest\x1a\".content.items.GetRevisionResponse\"\x00\x12\\\n\rListRevisions\x12#.content.items.ListRevisionsRequest\x1a$.content.items.ListRevisionsResponse\"\x00\x12\x42\n\x07\x41rchive\x12\x1d.content.items.ArchiveRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Y\n\x0c\x46indArchived\x12\".content.items.FindArchivedRequest\x1a#.content.items.FindArchivedResponse\"\x00\x12\x46\n\tUnarchive\x12\x1f.content.items.UnarchiveRequest\x1a\x16.google.protobuf.Empty\"\x00\x42.Z,github.com/perxteam/perxis/proto/items;itemsb\x06proto3'
+  serialized_pb=b'\n\x18perxis/items/items.proto\x12\rcontent.items\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1aperxis/common/common.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\"\'\n\x05\x45rror\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\r\n\x05\x66ield\x18\x02 \x01(\t\"3\n\x0b\x44\x65\x63odeError\x12$\n\x06\x65rrors\x18\x02 \x03(\x0b\x32\x14.content.items.Error\"7\n\x0fValidationError\x12$\n\x06\x65rrors\x18\x02 \x03(\x0b\x32\x14.content.items.Error\"9\n\x11ModificationError\x12$\n\x06\x65rrors\x18\x02 \x03(\x0b\x32\x14.content.items.Error\"\xd4\x05\n\x04Item\x12\n\n\x02id\x18\x01 \x01(\t\x12\x10\n\x08space_id\x18\x02 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x03 \x01(\t\x12\x15\n\rcollection_id\x18\x04 \x01(\t\x12(\n\x05state\x18\x05 \x01(\x0e\x32\x19.content.items.Item.State\x12\x32\n\x0e\x63reated_rev_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\ncreated_by\x18\x07 \x01(\t\x12.\n\ncreated_at\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x12\n\nupdated_by\x18\t \x01(\t\x12.\n\nupdated_at\x18\n \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12%\n\x04\x64\x61ta\x18\x0b \x01(\x0b\x32\x17.google.protobuf.Struct\x12;\n\x0ctranslations\x18\x0c \x03(\x0b\x32%.content.items.Item.TranslationsEntry\x12\x13\n\x0brevision_id\x18\r \x01(\t\x12\x30\n\x0cpublished_at\x18\x0e \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x14\n\x0cpublished_by\x18\x0f \x01(\t\x12/\n\x0b\x61rchived_at\x18\x10 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x13\n\x0b\x61rchived_by\x18\x11 \x01(\t\x12\x0e\n\x06locale\x18\x12 \x01(\t\x1aL\n\x11TranslationsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12&\n\x05value\x18\x02 \x01(\x0b\x32\x17.google.protobuf.Struct:\x02\x38\x01\"<\n\x05State\x12\t\n\x05\x44RAFT\x10\x00\x12\r\n\tPUBLISHED\x10\x01\x12\x0b\n\x07\x43HANGED\x10\x02\x12\x0c\n\x08\x41RCHIVED\x10\x03\"=\n\x06\x46ilter\x12\n\n\x02id\x18\x01 \x03(\t\x12\x1c\n\x04\x64\x61ta\x18\x02 \x03(\x0b\x32\x0e.common.Filter\x12\t\n\x01q\x18\x03 \x03(\t\"3\n\x0b\x46indOptions\x12$\n\x07options\x18\x02 \x01(\x0b\x32\x13.common.FindOptions\"(\n\x13GetPublishedOptions\x12\x11\n\tlocale_id\x18\x01 \x01(\t\"O\n\x14\x46indPublishedOptions\x12$\n\x07options\x18\x02 \x01(\x0b\x32\x13.common.FindOptions\x12\x11\n\tlocale_id\x18\x03 \x01(\t\";\n\x13\x46indArchivedOptions\x12$\n\x07options\x18\x02 \x01(\x0b\x32\x13.common.FindOptions\"2\n\rCreateRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"6\n\x0e\x43reateResponse\x12$\n\x07\x63reated\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"6\n\x11IntrospectRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\x8b\x01\n\x12IntrospectResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\x12\x0e\n\x06schema\x18\x02 \x01(\t\x12\x42\n\x11validation_errors\x18\x03 \x03(\x0b\x32\'.common.Error.BadRequest.FieldViolation\"V\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"0\n\x0bGetResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\x9a\x01\n\x0b\x46indRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12%\n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x15.content.items.Filter\x12+\n\x07options\x18\x05 \x01(\x0b\x32\x1a.content.items.FindOptions\"A\n\x0c\x46indResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\x12\r\n\x05total\x18\x02 \x01(\x05\"2\n\rUpdateRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"Y\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"3\n\x0ePublishRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\\\n\x10UnpublishRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"\x94\x01\n\x13GetPublishedRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x05 \x01(\t\x12\x33\n\x07options\x18\n \x01(\x0b\x32\".content.items.GetPublishedOptions\"9\n\x14GetPublishedResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\xac\x01\n\x14\x46indPublishedRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12%\n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x15.content.items.Filter\x12\x34\n\x07options\x18\n \x01(\x0b\x32#.content.items.FindPublishedOptions\"J\n\x15\x46indPublishedResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\x12\r\n\x05total\x18\x02 \x01(\x05\"s\n\x12GetRevisionRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\x12\x13\n\x0brevision_id\x18\x05 \x01(\t\"8\n\x13GetRevisionResponse\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"`\n\x14ListRevisionsRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\";\n\x15ListRevisionsResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\"3\n\x0e\x41rchiveRequest\x12!\n\x04item\x18\x01 \x01(\x0b\x32\x13.content.items.Item\"\\\n\x10UnarchiveRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12\x0f\n\x07item_id\x18\x04 \x01(\t\"\xaa\x01\n\x13\x46indArchivedRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12\x0e\n\x06\x65nv_id\x18\x02 \x01(\t\x12\x15\n\rcollection_id\x18\x03 \x01(\t\x12%\n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x15.content.items.Filter\x12\x33\n\x07options\x18\x06 \x01(\x0b\x32\".content.items.FindArchivedOptions\"I\n\x14\x46indArchivedResponse\x12\"\n\x05items\x18\x01 \x03(\x0b\x32\x13.content.items.Item\x12\r\n\x05total\x18\x02 \x01(\x05\x32\x8e\t\n\x05Items\x12G\n\x06\x43reate\x12\x1c.content.items.CreateRequest\x1a\x1d.content.items.CreateResponse\"\x00\x12S\n\nIntrospect\x12 .content.items.IntrospectRequest\x1a!.content.items.IntrospectResponse\"\x00\x12>\n\x03Get\x12\x19.content.items.GetRequest\x1a\x1a.content.items.GetResponse\"\x00\x12\x41\n\x04\x46ind\x12\x1a.content.items.FindRequest\x1a\x1b.content.items.FindResponse\"\x00\x12@\n\x06Update\x12\x1c.content.items.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12@\n\x06\x44\x65lete\x12\x1c.content.items.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x42\n\x07Publish\x12\x1d.content.items.PublishRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x46\n\tUnpublish\x12\x1f.content.items.UnpublishRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Y\n\x0cGetPublished\x12\".content.items.GetPublishedRequest\x1a#.content.items.GetPublishedResponse\"\x00\x12\\\n\rFindPublished\x12#.content.items.FindPublishedRequest\x1a$.content.items.FindPublishedResponse\"\x00\x12V\n\x0bGetRevision\x12!.content.items.GetRevisionRequest\x1a\".content.items.GetRevisionResponse\"\x00\x12\\\n\rListRevisions\x12#.content.items.ListRevisionsRequest\x1a$.content.items.ListRevisionsResponse\"\x00\x12\x42\n\x07\x41rchive\x12\x1d.content.items.ArchiveRequest\x1a\x16.google.protobuf.Empty\"\x00\x12Y\n\x0c\x46indArchived\x12\".content.items.FindArchivedRequest\x1a#.content.items.FindArchivedResponse\"\x00\x12\x46\n\tUnarchive\x12\x1f.content.items.UnarchiveRequest\x1a\x16.google.protobuf.Empty\"\x00\x42.Z,github.com/perxteam/perxis/proto/items;itemsb\x06proto3'
   ,
   dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,perxis_dot_common_dot_common__pb2.DESCRIPTOR,google_dot_protobuf_dot_timestamp__pb2.DESCRIPTOR,google_dot_protobuf_dot_struct__pb2.DESCRIPTOR,])
 
@@ -59,8 +59,8 @@ _ITEM_STATE = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=902,
-  serialized_end=962,
+  serialized_start=1038,
+  serialized_end=1098,
 )
 _sym_db.RegisterEnumDescriptor(_ITEM_STATE)
 
@@ -234,8 +234,8 @@ _ITEM_TRANSLATIONSENTRY = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=824,
-  serialized_end=900,
+  serialized_start=960,
+  serialized_end=1036,
 )
 
 _ITEM = _descriptor.Descriptor(
@@ -282,7 +282,7 @@ _ITEM = _descriptor.Descriptor(
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='created_at', full_name='content.items.Item.created_at', index=5,
+      name='created_rev_at', full_name='content.items.Item.created_rev_at', index=5,
       number=6, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
@@ -296,50 +296,78 @@ _ITEM = _descriptor.Descriptor(
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='data', full_name='content.items.Item.data', index=7,
+      name='created_at', full_name='content.items.Item.created_at', index=7,
       number=8, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='translations', full_name='content.items.Item.translations', index=8,
-      number=9, type=11, cpp_type=10, label=3,
+      name='updated_by', full_name='content.items.Item.updated_by', index=8,
+      number=9, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='updated_at', full_name='content.items.Item.updated_at', index=9,
+      number=10, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='data', full_name='content.items.Item.data', index=10,
+      number=11, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='translations', full_name='content.items.Item.translations', index=11,
+      number=12, type=11, cpp_type=10, label=3,
       has_default_value=False, default_value=[],
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='revision_id', full_name='content.items.Item.revision_id', index=9,
-      number=10, type=9, cpp_type=9, label=1,
+      name='revision_id', full_name='content.items.Item.revision_id', index=12,
+      number=13, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='published_at', full_name='content.items.Item.published_at', index=10,
-      number=11, type=11, cpp_type=10, label=1,
+      name='published_at', full_name='content.items.Item.published_at', index=13,
+      number=14, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='published_by', full_name='content.items.Item.published_by', index=11,
-      number=12, type=9, cpp_type=9, label=1,
+      name='published_by', full_name='content.items.Item.published_by', index=14,
+      number=15, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='archived_at', full_name='content.items.Item.archived_at', index=12,
-      number=13, type=11, cpp_type=10, label=1,
+      name='archived_at', full_name='content.items.Item.archived_at', index=15,
+      number=16, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='archived_by', full_name='content.items.Item.archived_by', index=13,
-      number=14, type=9, cpp_type=9, label=1,
+      name='archived_by', full_name='content.items.Item.archived_by', index=16,
+      number=17, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='locale', full_name='content.items.Item.locale', index=17,
+      number=18, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
@@ -358,7 +386,7 @@ _ITEM = _descriptor.Descriptor(
   oneofs=[
   ],
   serialized_start=374,
-  serialized_end=962,
+  serialized_end=1098,
 )
 
 
@@ -384,6 +412,13 @@ _FILTER = _descriptor.Descriptor(
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='q', full_name='content.items.Filter.q', index=2,
+      number=3, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
   ],
   extensions=[
   ],
@@ -396,8 +431,143 @@ _FILTER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=964,
-  serialized_end=1014,
+  serialized_start=1100,
+  serialized_end=1161,
+)
+
+
+_FINDOPTIONS = _descriptor.Descriptor(
+  name='FindOptions',
+  full_name='content.items.FindOptions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='options', full_name='content.items.FindOptions.options', index=0,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1163,
+  serialized_end=1214,
+)
+
+
+_GETPUBLISHEDOPTIONS = _descriptor.Descriptor(
+  name='GetPublishedOptions',
+  full_name='content.items.GetPublishedOptions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='locale_id', full_name='content.items.GetPublishedOptions.locale_id', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1216,
+  serialized_end=1256,
+)
+
+
+_FINDPUBLISHEDOPTIONS = _descriptor.Descriptor(
+  name='FindPublishedOptions',
+  full_name='content.items.FindPublishedOptions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='options', full_name='content.items.FindPublishedOptions.options', index=0,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='locale_id', full_name='content.items.FindPublishedOptions.locale_id', index=1,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1258,
+  serialized_end=1337,
+)
+
+
+_FINDARCHIVEDOPTIONS = _descriptor.Descriptor(
+  name='FindArchivedOptions',
+  full_name='content.items.FindArchivedOptions',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='options', full_name='content.items.FindArchivedOptions.options', index=0,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1339,
+  serialized_end=1398,
 )
 
 
@@ -428,8 +598,8 @@ _CREATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1016,
-  serialized_end=1066,
+  serialized_start=1400,
+  serialized_end=1450,
 )
 
 
@@ -460,8 +630,86 @@ _CREATERESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1068,
-  serialized_end=1122,
+  serialized_start=1452,
+  serialized_end=1506,
+)
+
+
+_INTROSPECTREQUEST = _descriptor.Descriptor(
+  name='IntrospectRequest',
+  full_name='content.items.IntrospectRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='item', full_name='content.items.IntrospectRequest.item', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1508,
+  serialized_end=1562,
+)
+
+
+_INTROSPECTRESPONSE = _descriptor.Descriptor(
+  name='IntrospectResponse',
+  full_name='content.items.IntrospectResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='item', full_name='content.items.IntrospectResponse.item', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='schema', full_name='content.items.IntrospectResponse.schema', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='validation_errors', full_name='content.items.IntrospectResponse.validation_errors', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1565,
+  serialized_end=1704,
 )
 
 
@@ -513,8 +761,8 @@ _GETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1124,
-  serialized_end=1210,
+  serialized_start=1706,
+  serialized_end=1792,
 )
 
 
@@ -545,8 +793,8 @@ _GETRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1212,
-  serialized_end=1260,
+  serialized_start=1794,
+  serialized_end=1842,
 )
 
 
@@ -605,8 +853,8 @@ _FINDREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1263,
-  serialized_end=1410,
+  serialized_start=1845,
+  serialized_end=1999,
 )
 
 
@@ -644,8 +892,8 @@ _FINDRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1412,
-  serialized_end=1477,
+  serialized_start=2001,
+  serialized_end=2066,
 )
 
 
@@ -676,8 +924,8 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1479,
-  serialized_end=1529,
+  serialized_start=2068,
+  serialized_end=2118,
 )
 
 
@@ -729,8 +977,8 @@ _DELETEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1531,
-  serialized_end=1620,
+  serialized_start=2120,
+  serialized_end=2209,
 )
 
 
@@ -761,8 +1009,8 @@ _PUBLISHREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1622,
-  serialized_end=1673,
+  serialized_start=2211,
+  serialized_end=2262,
 )
 
 
@@ -814,8 +1062,8 @@ _UNPUBLISHREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1675,
-  serialized_end=1767,
+  serialized_start=2264,
+  serialized_end=2356,
 )
 
 
@@ -849,16 +1097,16 @@ _GETPUBLISHEDREQUEST = _descriptor.Descriptor(
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='locale_id', full_name='content.items.GetPublishedRequest.locale_id', index=3,
-      number=4, type=9, cpp_type=9, label=1,
+      name='item_id', full_name='content.items.GetPublishedRequest.item_id', index=3,
+      number=5, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='item_id', full_name='content.items.GetPublishedRequest.item_id', index=4,
-      number=5, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
+      name='options', full_name='content.items.GetPublishedRequest.options', index=4,
+      number=10, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
@@ -874,8 +1122,8 @@ _GETPUBLISHEDREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1769,
-  serialized_end=1883,
+  serialized_start=2359,
+  serialized_end=2507,
 )
 
 
@@ -906,8 +1154,8 @@ _GETPUBLISHEDRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1885,
-  serialized_end=1942,
+  serialized_start=2509,
+  serialized_end=2566,
 )
 
 
@@ -941,22 +1189,15 @@ _FINDPUBLISHEDREQUEST = _descriptor.Descriptor(
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='locale_id', full_name='content.items.FindPublishedRequest.locale_id', index=3,
-      number=4, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-    _descriptor.FieldDescriptor(
-      name='filter', full_name='content.items.FindPublishedRequest.filter', index=4,
-      number=5, type=11, cpp_type=10, label=1,
+      name='filter', full_name='content.items.FindPublishedRequest.filter', index=3,
+      number=4, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='options', full_name='content.items.FindPublishedRequest.options', index=5,
-      number=6, type=11, cpp_type=10, label=1,
+      name='options', full_name='content.items.FindPublishedRequest.options', index=4,
+      number=10, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
@@ -973,8 +1214,8 @@ _FINDPUBLISHEDREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=1945,
-  serialized_end=2120,
+  serialized_start=2569,
+  serialized_end=2741,
 )
 
 
@@ -1012,8 +1253,8 @@ _FINDPUBLISHEDRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2122,
-  serialized_end=2196,
+  serialized_start=2743,
+  serialized_end=2817,
 )
 
 
@@ -1072,8 +1313,8 @@ _GETREVISIONREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2198,
-  serialized_end=2313,
+  serialized_start=2819,
+  serialized_end=2934,
 )
 
 
@@ -1104,8 +1345,8 @@ _GETREVISIONRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2315,
-  serialized_end=2371,
+  serialized_start=2936,
+  serialized_end=2992,
 )
 
 
@@ -1157,8 +1398,8 @@ _LISTREVISIONSREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2373,
-  serialized_end=2469,
+  serialized_start=2994,
+  serialized_end=3090,
 )
 
 
@@ -1189,8 +1430,8 @@ _LISTREVISIONSRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2471,
-  serialized_end=2530,
+  serialized_start=3092,
+  serialized_end=3151,
 )
 
 
@@ -1221,8 +1462,8 @@ _ARCHIVEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2532,
-  serialized_end=2583,
+  serialized_start=3153,
+  serialized_end=3204,
 )
 
 
@@ -1274,8 +1515,8 @@ _UNARCHIVEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2585,
-  serialized_end=2677,
+  serialized_start=3206,
+  serialized_end=3298,
 )
 
 
@@ -1310,7 +1551,7 @@ _FINDARCHIVEDREQUEST = _descriptor.Descriptor(
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
       name='filter', full_name='content.items.FindArchivedRequest.filter', index=3,
-      number=5, type=11, cpp_type=10, label=1,
+      number=4, type=11, cpp_type=10, label=1,
       has_default_value=False, default_value=None,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
@@ -1334,8 +1575,8 @@ _FINDARCHIVEDREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2680,
-  serialized_end=2835,
+  serialized_start=3301,
+  serialized_end=3471,
 )
 
 
@@ -1373,8 +1614,8 @@ _FINDARCHIVEDRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2837,
-  serialized_end=2910,
+  serialized_start=3473,
+  serialized_end=3546,
 )
 
 _DECODEERROR.fields_by_name['errors'].message_type = _ERROR
@@ -1383,30 +1624,39 @@ _MODIFICATIONERROR.fields_by_name['errors'].message_type = _ERROR
 _ITEM_TRANSLATIONSENTRY.fields_by_name['value'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT
 _ITEM_TRANSLATIONSENTRY.containing_type = _ITEM
 _ITEM.fields_by_name['state'].enum_type = _ITEM_STATE
+_ITEM.fields_by_name['created_rev_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
 _ITEM.fields_by_name['created_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
+_ITEM.fields_by_name['updated_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
 _ITEM.fields_by_name['data'].message_type = google_dot_protobuf_dot_struct__pb2._STRUCT
 _ITEM.fields_by_name['translations'].message_type = _ITEM_TRANSLATIONSENTRY
 _ITEM.fields_by_name['published_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
 _ITEM.fields_by_name['archived_at'].message_type = google_dot_protobuf_dot_timestamp__pb2._TIMESTAMP
 _ITEM_STATE.containing_type = _ITEM
 _FILTER.fields_by_name['data'].message_type = perxis_dot_common_dot_common__pb2._FILTER
+_FINDOPTIONS.fields_by_name['options'].message_type = perxis_dot_common_dot_common__pb2._FINDOPTIONS
+_FINDPUBLISHEDOPTIONS.fields_by_name['options'].message_type = perxis_dot_common_dot_common__pb2._FINDOPTIONS
+_FINDARCHIVEDOPTIONS.fields_by_name['options'].message_type = perxis_dot_common_dot_common__pb2._FINDOPTIONS
 _CREATEREQUEST.fields_by_name['item'].message_type = _ITEM
 _CREATERESPONSE.fields_by_name['created'].message_type = _ITEM
+_INTROSPECTREQUEST.fields_by_name['item'].message_type = _ITEM
+_INTROSPECTRESPONSE.fields_by_name['item'].message_type = _ITEM
+_INTROSPECTRESPONSE.fields_by_name['validation_errors'].message_type = perxis_dot_common_dot_common__pb2._ERROR_BADREQUEST_FIELDVIOLATION
 _GETRESPONSE.fields_by_name['item'].message_type = _ITEM
 _FINDREQUEST.fields_by_name['filter'].message_type = _FILTER
-_FINDREQUEST.fields_by_name['options'].message_type = perxis_dot_common_dot_common__pb2._FINDOPTIONS
+_FINDREQUEST.fields_by_name['options'].message_type = _FINDOPTIONS
 _FINDRESPONSE.fields_by_name['items'].message_type = _ITEM
 _UPDATEREQUEST.fields_by_name['item'].message_type = _ITEM
 _PUBLISHREQUEST.fields_by_name['item'].message_type = _ITEM
+_GETPUBLISHEDREQUEST.fields_by_name['options'].message_type = _GETPUBLISHEDOPTIONS
 _GETPUBLISHEDRESPONSE.fields_by_name['item'].message_type = _ITEM
 _FINDPUBLISHEDREQUEST.fields_by_name['filter'].message_type = _FILTER
-_FINDPUBLISHEDREQUEST.fields_by_name['options'].message_type = perxis_dot_common_dot_common__pb2._FINDOPTIONS
+_FINDPUBLISHEDREQUEST.fields_by_name['options'].message_type = _FINDPUBLISHEDOPTIONS
 _FINDPUBLISHEDRESPONSE.fields_by_name['items'].message_type = _ITEM
 _GETREVISIONRESPONSE.fields_by_name['item'].message_type = _ITEM
 _LISTREVISIONSRESPONSE.fields_by_name['items'].message_type = _ITEM
 _ARCHIVEREQUEST.fields_by_name['item'].message_type = _ITEM
 _FINDARCHIVEDREQUEST.fields_by_name['filter'].message_type = _FILTER
-_FINDARCHIVEDREQUEST.fields_by_name['options'].message_type = perxis_dot_common_dot_common__pb2._FINDOPTIONS
+_FINDARCHIVEDREQUEST.fields_by_name['options'].message_type = _FINDARCHIVEDOPTIONS
 _FINDARCHIVEDRESPONSE.fields_by_name['items'].message_type = _ITEM
 DESCRIPTOR.message_types_by_name['Error'] = _ERROR
 DESCRIPTOR.message_types_by_name['DecodeError'] = _DECODEERROR
@@ -1414,8 +1664,14 @@ DESCRIPTOR.message_types_by_name['ValidationError'] = _VALIDATIONERROR
 DESCRIPTOR.message_types_by_name['ModificationError'] = _MODIFICATIONERROR
 DESCRIPTOR.message_types_by_name['Item'] = _ITEM
 DESCRIPTOR.message_types_by_name['Filter'] = _FILTER
+DESCRIPTOR.message_types_by_name['FindOptions'] = _FINDOPTIONS
+DESCRIPTOR.message_types_by_name['GetPublishedOptions'] = _GETPUBLISHEDOPTIONS
+DESCRIPTOR.message_types_by_name['FindPublishedOptions'] = _FINDPUBLISHEDOPTIONS
+DESCRIPTOR.message_types_by_name['FindArchivedOptions'] = _FINDARCHIVEDOPTIONS
 DESCRIPTOR.message_types_by_name['CreateRequest'] = _CREATEREQUEST
 DESCRIPTOR.message_types_by_name['CreateResponse'] = _CREATERESPONSE
+DESCRIPTOR.message_types_by_name['IntrospectRequest'] = _INTROSPECTREQUEST
+DESCRIPTOR.message_types_by_name['IntrospectResponse'] = _INTROSPECTRESPONSE
 DESCRIPTOR.message_types_by_name['GetRequest'] = _GETREQUEST
 DESCRIPTOR.message_types_by_name['GetResponse'] = _GETRESPONSE
 DESCRIPTOR.message_types_by_name['FindRequest'] = _FINDREQUEST
@@ -1488,6 +1744,34 @@ Filter = _reflection.GeneratedProtocolMessageType('Filter', (_message.Message,),
   })
 _sym_db.RegisterMessage(Filter)
 
+FindOptions = _reflection.GeneratedProtocolMessageType('FindOptions', (_message.Message,), {
+  'DESCRIPTOR' : _FINDOPTIONS,
+  '__module__' : 'perxis.items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.FindOptions)
+  })
+_sym_db.RegisterMessage(FindOptions)
+
+GetPublishedOptions = _reflection.GeneratedProtocolMessageType('GetPublishedOptions', (_message.Message,), {
+  'DESCRIPTOR' : _GETPUBLISHEDOPTIONS,
+  '__module__' : 'perxis.items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.GetPublishedOptions)
+  })
+_sym_db.RegisterMessage(GetPublishedOptions)
+
+FindPublishedOptions = _reflection.GeneratedProtocolMessageType('FindPublishedOptions', (_message.Message,), {
+  'DESCRIPTOR' : _FINDPUBLISHEDOPTIONS,
+  '__module__' : 'perxis.items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.FindPublishedOptions)
+  })
+_sym_db.RegisterMessage(FindPublishedOptions)
+
+FindArchivedOptions = _reflection.GeneratedProtocolMessageType('FindArchivedOptions', (_message.Message,), {
+  'DESCRIPTOR' : _FINDARCHIVEDOPTIONS,
+  '__module__' : 'perxis.items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.FindArchivedOptions)
+  })
+_sym_db.RegisterMessage(FindArchivedOptions)
+
 CreateRequest = _reflection.GeneratedProtocolMessageType('CreateRequest', (_message.Message,), {
   'DESCRIPTOR' : _CREATEREQUEST,
   '__module__' : 'perxis.items.items_pb2'
@@ -1502,6 +1786,20 @@ CreateResponse = _reflection.GeneratedProtocolMessageType('CreateResponse', (_me
   })
 _sym_db.RegisterMessage(CreateResponse)
 
+IntrospectRequest = _reflection.GeneratedProtocolMessageType('IntrospectRequest', (_message.Message,), {
+  'DESCRIPTOR' : _INTROSPECTREQUEST,
+  '__module__' : 'perxis.items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.IntrospectRequest)
+  })
+_sym_db.RegisterMessage(IntrospectRequest)
+
+IntrospectResponse = _reflection.GeneratedProtocolMessageType('IntrospectResponse', (_message.Message,), {
+  'DESCRIPTOR' : _INTROSPECTRESPONSE,
+  '__module__' : 'perxis.items.items_pb2'
+  # @@protoc_insertion_point(class_scope:content.items.IntrospectResponse)
+  })
+_sym_db.RegisterMessage(IntrospectResponse)
+
 GetRequest = _reflection.GeneratedProtocolMessageType('GetRequest', (_message.Message,), {
   'DESCRIPTOR' : _GETREQUEST,
   '__module__' : 'perxis.items.items_pb2'
@@ -1653,8 +1951,8 @@ _ITEMS = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=2913,
-  serialized_end=3994,
+  serialized_start=3549,
+  serialized_end=4715,
   methods=[
   _descriptor.MethodDescriptor(
     name='Create',
@@ -1666,10 +1964,20 @@ _ITEMS = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='Introspect',
+    full_name='content.items.Items.Introspect',
+    index=1,
+    containing_service=None,
+    input_type=_INTROSPECTREQUEST,
+    output_type=_INTROSPECTRESPONSE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
   _descriptor.MethodDescriptor(
     name='Get',
     full_name='content.items.Items.Get',
-    index=1,
+    index=2,
     containing_service=None,
     input_type=_GETREQUEST,
     output_type=_GETRESPONSE,
@@ -1679,7 +1987,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='Find',
     full_name='content.items.Items.Find',
-    index=2,
+    index=3,
     containing_service=None,
     input_type=_FINDREQUEST,
     output_type=_FINDRESPONSE,
@@ -1689,7 +1997,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='Update',
     full_name='content.items.Items.Update',
-    index=3,
+    index=4,
     containing_service=None,
     input_type=_UPDATEREQUEST,
     output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
@@ -1699,7 +2007,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='Delete',
     full_name='content.items.Items.Delete',
-    index=4,
+    index=5,
     containing_service=None,
     input_type=_DELETEREQUEST,
     output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
@@ -1709,7 +2017,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='Publish',
     full_name='content.items.Items.Publish',
-    index=5,
+    index=6,
     containing_service=None,
     input_type=_PUBLISHREQUEST,
     output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
@@ -1719,7 +2027,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='Unpublish',
     full_name='content.items.Items.Unpublish',
-    index=6,
+    index=7,
     containing_service=None,
     input_type=_UNPUBLISHREQUEST,
     output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
@@ -1729,7 +2037,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetPublished',
     full_name='content.items.Items.GetPublished',
-    index=7,
+    index=8,
     containing_service=None,
     input_type=_GETPUBLISHEDREQUEST,
     output_type=_GETPUBLISHEDRESPONSE,
@@ -1739,7 +2047,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='FindPublished',
     full_name='content.items.Items.FindPublished',
-    index=8,
+    index=9,
     containing_service=None,
     input_type=_FINDPUBLISHEDREQUEST,
     output_type=_FINDPUBLISHEDRESPONSE,
@@ -1749,7 +2057,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetRevision',
     full_name='content.items.Items.GetRevision',
-    index=9,
+    index=10,
     containing_service=None,
     input_type=_GETREVISIONREQUEST,
     output_type=_GETREVISIONRESPONSE,
@@ -1759,7 +2067,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='ListRevisions',
     full_name='content.items.Items.ListRevisions',
-    index=10,
+    index=11,
     containing_service=None,
     input_type=_LISTREVISIONSREQUEST,
     output_type=_LISTREVISIONSRESPONSE,
@@ -1769,7 +2077,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='Archive',
     full_name='content.items.Items.Archive',
-    index=11,
+    index=12,
     containing_service=None,
     input_type=_ARCHIVEREQUEST,
     output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
@@ -1779,7 +2087,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='FindArchived',
     full_name='content.items.Items.FindArchived',
-    index=12,
+    index=13,
     containing_service=None,
     input_type=_FINDARCHIVEDREQUEST,
     output_type=_FINDARCHIVEDRESPONSE,
@@ -1789,7 +2097,7 @@ _ITEMS = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='Unarchive',
     full_name='content.items.Items.Unarchive',
-    index=13,
+    index=14,
     containing_service=None,
     input_type=_UNARCHIVEREQUEST,
     output_type=google_dot_protobuf_dot_empty__pb2._EMPTY,
diff --git a/perxis/items/items_pb2_grpc.py b/perxis/items/items_pb2_grpc.py
index 6a09d34e09bda3ddbe837cb1a3995c7c52b6d3b2..c850cca1189618ab05482e41d2e516a6bd5f9af9 100644
--- a/perxis/items/items_pb2_grpc.py
+++ b/perxis/items/items_pb2_grpc.py
@@ -7,7 +7,9 @@ from perxis.items import items_pb2 as perxis_dot_items_dot_items__pb2
 
 
 class ItemsStub(object):
-    """Missing associated documentation comment in .proto file."""
+    """*
+    Сервис API элементов
+    """
 
     def __init__(self, channel):
         """Constructor.
@@ -20,6 +22,11 @@ class ItemsStub(object):
                 request_serializer=perxis_dot_items_dot_items__pb2.CreateRequest.SerializeToString,
                 response_deserializer=perxis_dot_items_dot_items__pb2.CreateResponse.FromString,
                 )
+        self.Introspect = channel.unary_unary(
+                '/content.items.Items/Introspect',
+                request_serializer=perxis_dot_items_dot_items__pb2.IntrospectRequest.SerializeToString,
+                response_deserializer=perxis_dot_items_dot_items__pb2.IntrospectResponse.FromString,
+                )
         self.Get = channel.unary_unary(
                 '/content.items.Items/Get',
                 request_serializer=perxis_dot_items_dot_items__pb2.GetRequest.SerializeToString,
@@ -88,22 +95,38 @@ class ItemsStub(object):
 
 
 class ItemsServicer(object):
-    """Missing associated documentation comment in .proto file."""
+    """*
+    Сервис API элементов
+    """
 
     def Create(self, request, context):
-        """Missing associated documentation comment in .proto file."""
+        """*
+        Создать запись
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Introspect(self, request, context):
+        """*
+        Валидация данных записи
+        """
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
     def Get(self, request, context):
-        """Missing associated documentation comment in .proto file."""
+        """*
+        Получение записи по идентификатору
+        """
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
     def Find(self, request, context):
-        """Missing associated documentation comment in .proto file."""
+        """*
+        Поиск по текущим записям
+        """
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
@@ -182,6 +205,11 @@ def add_ItemsServicer_to_server(servicer, server):
                     request_deserializer=perxis_dot_items_dot_items__pb2.CreateRequest.FromString,
                     response_serializer=perxis_dot_items_dot_items__pb2.CreateResponse.SerializeToString,
             ),
+            'Introspect': grpc.unary_unary_rpc_method_handler(
+                    servicer.Introspect,
+                    request_deserializer=perxis_dot_items_dot_items__pb2.IntrospectRequest.FromString,
+                    response_serializer=perxis_dot_items_dot_items__pb2.IntrospectResponse.SerializeToString,
+            ),
             'Get': grpc.unary_unary_rpc_method_handler(
                     servicer.Get,
                     request_deserializer=perxis_dot_items_dot_items__pb2.GetRequest.FromString,
@@ -255,7 +283,9 @@ def add_ItemsServicer_to_server(servicer, server):
 
  # This class is part of an EXPERIMENTAL API.
 class Items(object):
-    """Missing associated documentation comment in .proto file."""
+    """*
+    Сервис API элементов
+    """
 
     @staticmethod
     def Create(request,
@@ -274,6 +304,23 @@ class Items(object):
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
+    @staticmethod
+    def Introspect(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/content.items.Items/Introspect',
+            perxis_dot_items_dot_items__pb2.IntrospectRequest.SerializeToString,
+            perxis_dot_items_dot_items__pb2.IntrospectResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
     @staticmethod
     def Get(request,
             target,
diff --git a/perxis/spaces/spaces_pb2.py b/perxis/spaces/spaces_pb2.py
index 5786074d75b5579c8780018868e4aad46f2b12a7..f37cade453b48a9bfb06e72f7c99a41729b1cc88 100644
--- a/perxis/spaces/spaces_pb2.py
+++ b/perxis/spaces/spaces_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=b'Z.github.com/perxteam/perxis/proto/spaces;spaces',
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x1aperxis/spaces/spaces.proto\x12\x0e\x63ontent.spaces\x1a\x1bgoogle/protobuf/empty.proto\"\x94\x01\n\x05Space\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06org_id\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12$\n\x05state\x18\x05 \x01(\x0e\x32\x15.content.spaces.State\x12&\n\x06\x63onfig\x18\n \x01(\x0b\x32\x16.content.spaces.Config\"\x1a\n\x06\x43onfig\x12\x10\n\x08\x66\x65\x61tures\x18\x01 \x03(\t\"5\n\rCreateRequest\x12$\n\x05space\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"8\n\x0e\x43reateResponse\x12&\n\x07\x63reated\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"\x1e\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"3\n\x0bGetResponse\x12$\n\x05space\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"\x1d\n\x0bListRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"5\n\x0cListResponse\x12%\n\x06spaces\x18\x01 \x03(\x0b\x32\x15.content.spaces.Space\"5\n\rUpdateRequest\x12$\n\x05space\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"O\n\x13UpdateConfigRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12&\n\x06\x63onfig\x18\x02 \x01(\x0b\x32\x16.content.spaces.Config\"!\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t*p\n\x05State\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03NEW\x10\x01\x12\t\n\x05READY\x10\x02\x12\r\n\tPREPARING\x10\x03\x12\x0f\n\x0bMAINTENANCE\x10\x04\x12\r\n\tMIGRATION\x10\x05\x12\x0c\n\x08\x44\x45LETING\x10\x06\x12\t\n\x05\x45RROR\x10\x07\x32\xaf\x03\n\x06Spaces\x12I\n\x06\x43reate\x12\x1d.content.spaces.CreateRequest\x1a\x1e.content.spaces.CreateResponse\"\x00\x12@\n\x03Get\x12\x1a.content.spaces.GetRequest\x1a\x1b.content.spaces.GetResponse\"\x00\x12\x43\n\x04List\x12\x1b.content.spaces.ListRequest\x1a\x1c.content.spaces.ListResponse\"\x00\x12\x41\n\x06Update\x12\x1d.content.spaces.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12M\n\x0cUpdateConfig\x12#.content.spaces.UpdateConfigRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x41\n\x06\x44\x65lete\x12\x1d.content.spaces.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x30Z.github.com/perxteam/perxis/proto/spaces;spacesb\x06proto3'
+  serialized_pb=b'\n\x1aperxis/spaces/spaces.proto\x12\x0e\x63ontent.spaces\x1a\x1bgoogle/protobuf/empty.proto\"\x94\x01\n\x05Space\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06org_id\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12$\n\x05state\x18\x05 \x01(\x0e\x32\x15.content.spaces.State\x12&\n\x06\x63onfig\x18\n \x01(\x0b\x32\x16.content.spaces.Config\"Q\n\x06\x43onfig\x12\x10\n\x08\x66\x65\x61tures\x18\x01 \x03(\t\x12\x17\n\x0f\x61llow_anonymous\x18\x02 \x01(\x08\x12\x1c\n\x14\x61llow_any_authorized\x18\x03 \x01(\x08\"5\n\rCreateRequest\x12$\n\x05space\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"8\n\x0e\x43reateResponse\x12&\n\x07\x63reated\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"\x1e\n\nGetRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\"3\n\x0bGetResponse\x12$\n\x05space\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"\x1d\n\x0bListRequest\x12\x0e\n\x06org_id\x18\x01 \x01(\t\"5\n\x0cListResponse\x12%\n\x06spaces\x18\x01 \x03(\x0b\x32\x15.content.spaces.Space\"5\n\rUpdateRequest\x12$\n\x05space\x18\x01 \x01(\x0b\x32\x15.content.spaces.Space\"O\n\x13UpdateConfigRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t\x12&\n\x06\x63onfig\x18\x02 \x01(\x0b\x32\x16.content.spaces.Config\"!\n\rDeleteRequest\x12\x10\n\x08space_id\x18\x01 \x01(\t*p\n\x05State\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x07\n\x03NEW\x10\x01\x12\t\n\x05READY\x10\x02\x12\r\n\tPREPARING\x10\x03\x12\x0f\n\x0bMAINTENANCE\x10\x04\x12\r\n\tMIGRATION\x10\x05\x12\x0c\n\x08\x44\x45LETING\x10\x06\x12\t\n\x05\x45RROR\x10\x07\x32\xaf\x03\n\x06Spaces\x12I\n\x06\x43reate\x12\x1d.content.spaces.CreateRequest\x1a\x1e.content.spaces.CreateResponse\"\x00\x12@\n\x03Get\x12\x1a.content.spaces.GetRequest\x1a\x1b.content.spaces.GetResponse\"\x00\x12\x43\n\x04List\x12\x1b.content.spaces.ListRequest\x1a\x1c.content.spaces.ListResponse\"\x00\x12\x41\n\x06Update\x12\x1d.content.spaces.UpdateRequest\x1a\x16.google.protobuf.Empty\"\x00\x12M\n\x0cUpdateConfig\x12#.content.spaces.UpdateConfigRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x41\n\x06\x44\x65lete\x12\x1d.content.spaces.DeleteRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x30Z.github.com/perxteam/perxis/proto/spaces;spacesb\x06proto3'
   ,
   dependencies=[google_dot_protobuf_dot_empty__pb2.DESCRIPTOR,])
 
@@ -75,8 +75,8 @@ _STATE = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=709,
-  serialized_end=821,
+  serialized_start=764,
+  serialized_end=876,
 )
 _sym_db.RegisterEnumDescriptor(_STATE)
 
@@ -174,6 +174,20 @@ _CONFIG = _descriptor.Descriptor(
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='allow_anonymous', full_name='content.spaces.Config.allow_anonymous', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='allow_any_authorized', full_name='content.spaces.Config.allow_any_authorized', index=2,
+      number=3, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
   ],
   extensions=[
   ],
@@ -187,7 +201,7 @@ _CONFIG = _descriptor.Descriptor(
   oneofs=[
   ],
   serialized_start=226,
-  serialized_end=252,
+  serialized_end=307,
 )
 
 
@@ -218,8 +232,8 @@ _CREATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=254,
-  serialized_end=307,
+  serialized_start=309,
+  serialized_end=362,
 )
 
 
@@ -250,8 +264,8 @@ _CREATERESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=309,
-  serialized_end=365,
+  serialized_start=364,
+  serialized_end=420,
 )
 
 
@@ -282,8 +296,8 @@ _GETREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=367,
-  serialized_end=397,
+  serialized_start=422,
+  serialized_end=452,
 )
 
 
@@ -314,8 +328,8 @@ _GETRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=399,
-  serialized_end=450,
+  serialized_start=454,
+  serialized_end=505,
 )
 
 
@@ -346,8 +360,8 @@ _LISTREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=452,
-  serialized_end=481,
+  serialized_start=507,
+  serialized_end=536,
 )
 
 
@@ -378,8 +392,8 @@ _LISTRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=483,
-  serialized_end=536,
+  serialized_start=538,
+  serialized_end=591,
 )
 
 
@@ -410,8 +424,8 @@ _UPDATEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=538,
-  serialized_end=591,
+  serialized_start=593,
+  serialized_end=646,
 )
 
 
@@ -449,8 +463,8 @@ _UPDATECONFIGREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=593,
-  serialized_end=672,
+  serialized_start=648,
+  serialized_end=727,
 )
 
 
@@ -481,8 +495,8 @@ _DELETEREQUEST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=674,
-  serialized_end=707,
+  serialized_start=729,
+  serialized_end=762,
 )
 
 _SPACE.fields_by_name['state'].enum_type = _STATE
@@ -594,8 +608,8 @@ _SPACES = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=824,
-  serialized_end=1255,
+  serialized_start=879,
+  serialized_end=1310,
   methods=[
   _descriptor.MethodDescriptor(
     name='Create',
diff --git a/perxis/status/__init__.py b/perxis/status/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/perxis/status/status_pb2.py b/perxis/status/status_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9d00c310fc3e39adee98df79a32752933c49924
--- /dev/null
+++ b/perxis/status/status_pb2.py
@@ -0,0 +1,88 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: perxis/status/status.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='perxis/status/status.proto',
+  package='google.rpc',
+  syntax='proto3',
+  serialized_options=b'\n\016com.google.rpcB\013StatusProtoP\001',
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x1aperxis/status/status.proto\x12\ngoogle.rpc\x1a\x19google/protobuf/any.proto\"N\n\x06Status\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\x12%\n\x07\x64\x65tails\x18\x03 \x03(\x0b\x32\x14.google.protobuf.AnyB\x1f\n\x0e\x63om.google.rpcB\x0bStatusProtoP\x01\x62\x06proto3'
+  ,
+  dependencies=[google_dot_protobuf_dot_any__pb2.DESCRIPTOR,])
+
+
+
+
+_STATUS = _descriptor.Descriptor(
+  name='Status',
+  full_name='google.rpc.Status',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='code', full_name='google.rpc.Status.code', index=0,
+      number=1, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='message', full_name='google.rpc.Status.message', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='details', full_name='google.rpc.Status.details', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=69,
+  serialized_end=147,
+)
+
+_STATUS.fields_by_name['details'].message_type = google_dot_protobuf_dot_any__pb2._ANY
+DESCRIPTOR.message_types_by_name['Status'] = _STATUS
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Status = _reflection.GeneratedProtocolMessageType('Status', (_message.Message,), {
+  'DESCRIPTOR' : _STATUS,
+  '__module__' : 'perxis.status.status_pb2'
+  # @@protoc_insertion_point(class_scope:google.rpc.Status)
+  })
+_sym_db.RegisterMessage(Status)
+
+
+DESCRIPTOR._options = None
+# @@protoc_insertion_point(module_scope)
diff --git a/perxis/status/status_pb2_grpc.py b/perxis/status/status_pb2_grpc.py
new file mode 100644
index 0000000000000000000000000000000000000000..2daafffebfc817aefe8fcb96eaec25e65b3903e8
--- /dev/null
+++ b/perxis/status/status_pb2_grpc.py
@@ -0,0 +1,4 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
diff --git a/proto/perxis/collections/collections.proto b/proto/perxis/collections/collections.proto
index bf291507e6c568a0887c771b55005d10fd7e952d..38d9380d95e1c5857f74d3377501feffc5e7b8ac 100644
--- a/proto/perxis/collections/collections.proto
+++ b/proto/perxis/collections/collections.proto
@@ -2,11 +2,19 @@ syntax = "proto3";
 
 import "google/protobuf/empty.proto";
 //import "google/protobuf/wrappers.proto";
+import "perxis/common/common.proto";
 
 option go_package = "github.com/perxteam/perxis/proto/collections;collections";
 
 package content.collections;
 
+message Access {
+  repeated common.Action actions = 1;
+  repeated string hidden_fields = 5;
+  repeated string readonly_fields = 6;
+  repeated string writeonly_fields = 7;
+}
+
 message Collection {
   string id = 1;
   string space_id = 2;
@@ -15,6 +23,16 @@ message Collection {
   optional bool single = 5;
   optional bool system = 6;
   string schema = 7;
+
+  message View {
+    string space_id = 1;
+    string env_id = 2;
+    string collection_id  = 3;
+    string filter = 4;
+  }
+  View view = 9;
+
+  Access access = 20;
 }
 
 message CreateRequest {
diff --git a/proto/perxis/common/common.proto b/proto/perxis/common/common.proto
index 0744d5892b1a53600e7256c082ef72fbe77a4233..337d0a8a489e83b56330bff1ca5ac7ef2b2563d8 100644
--- a/proto/perxis/common/common.proto
+++ b/proto/perxis/common/common.proto
@@ -78,6 +78,7 @@ message Rule {
   repeated string hidden_fields = 5;
   repeated string readonly_fields = 6;
   repeated string writeonly_fields = 7;
+  string filter = 8;
 }
 
 message Collaborator {
diff --git a/proto/perxis/delivery/delivery.proto b/proto/perxis/delivery/delivery.proto
index 7577a3c540cebd92c524bdb1ac102e5ddfb96cd5..2245f2796ec7c2e6bc986acaecac2bd5af22dd3c 100644
--- a/proto/perxis/delivery/delivery.proto
+++ b/proto/perxis/delivery/delivery.proto
@@ -4,7 +4,6 @@ import "perxis/locales/locales.proto";
 import "perxis/environments/environments.proto";
 import "perxis/collections/collections.proto";
 import "perxis/items/items.proto";
-import "perxis/common/common.proto";
 
 option go_package = "github.com/perxteam/perxis/proto/delivery;delivery";
 
@@ -56,8 +55,8 @@ message GetItemRequest {
   string space_id = 1;
   string env_id = 2;
   string collection_id = 3;
-  string locale_id = 4;
   string item_id = 5;
+  content.items.GetPublishedOptions options = 6;
 }
 message GetItemResponse {
   content.items.Item item = 1;
@@ -69,7 +68,7 @@ message FindItemsRequest {
   string collection_id = 3;
   string locale_id = 4;
   content.items.Filter filter = 5;
-  common.FindOptions options = 6;
+  content.items.FindPublishedOptions options = 6;
 }
 message FindItemsResponse{
   repeated content.items.Item items = 1;
diff --git a/proto/perxis/features/features.proto b/proto/perxis/features/features.proto
new file mode 100644
index 0000000000000000000000000000000000000000..ae26fc9b587788158ba8529a7eb5500aeb23a6d3
--- /dev/null
+++ b/proto/perxis/features/features.proto
@@ -0,0 +1,23 @@
+syntax = "proto3";
+
+option go_package = "github.com/perxteam/perxis/proto/features;features";
+
+package content.features;
+
+// Сущности
+
+message FeatureDescription {
+  string name = 1;
+  string revision = 2;
+  repeated string dependencies = 3;
+}
+
+message ListRequest{}
+message ListResponse{
+    repeated FeatureDescription descriptions = 1;
+}
+
+service Features {
+  // List получить все возможности зарегистрированные в системе
+  rpc List(ListRequest) returns(ListResponse) {}
+}
\ No newline at end of file
diff --git a/proto/perxis/file/file.proto b/proto/perxis/files/files.proto
similarity index 97%
rename from proto/perxis/file/file.proto
rename to proto/perxis/files/files.proto
index 98efa87abbbce362cc39ac9f4a9346036e34bba2..81ae4980b02413c22468bdc6b5c0f3836c127d39 100644
--- a/proto/perxis/file/file.proto
+++ b/proto/perxis/files/files.proto
@@ -2,9 +2,9 @@ syntax = "proto3";
 
 import "google/protobuf/empty.proto";
 
-option go_package = "github.com/perxteam/perxis/proto/file;file";
+option go_package = "github.com/perxteam/perxis/proto/files;files";
 
-package file;
+package files;
 
 // Сущности
 
@@ -81,7 +81,7 @@ message DeleteFileRequest {
 }
 message DeleteFileResponse {}
 
-service FileService {
+service Files {
   // StartUpload - инициирует процедуру загрузки файла в файловое хранилище.
   // Используется клиентским приложением для начала загрузки файла
   rpc StartUpload(StartUploadRequest) returns(StartUploadResponse) {}
diff --git a/proto/perxis/image/image.proto b/proto/perxis/images/images.proto
similarity index 83%
rename from proto/perxis/image/image.proto
rename to proto/perxis/images/images.proto
index 13d22d6ed9306c4123befbf1fe76742f951999fb..72771e9eefc6d324804ca5248034da574eb3eec9 100644
--- a/proto/perxis/image/image.proto
+++ b/proto/perxis/images/images.proto
@@ -1,10 +1,10 @@
 syntax = "proto3";
 
-import "perxis/file/file.proto";
+import "perxis/files/files.proto";
 
-option go_package = "github.com/perxteam/perxis/proto/image;image";
+option go_package = "github.com/perxteam/perxis/proto/images;images";
 
-package image;
+package images;
 
 message Param {
   string op = 1;
@@ -17,16 +17,16 @@ message GetRequest {
     repeated Param params = 1;
   }
 
-  file.File source = 1;
+  files.File source = 1;
   GetOptions opts = 2;
 }
 
 message GetResponse {
-  file.File result = 1;
+  files.File result = 1;
 }
 
 // ImageService - сервис для обработки изображений
-service ImageService {
+service Images {
 
   // Get - к файлу, идентификатор которого передан в запросе, применяются параметры.
   // Может быть передано несколько параметров, порядок учитывается при обработке
diff --git a/proto/perxis/items/items.proto b/proto/perxis/items/items.proto
index 88f188c7c7e65f853a9fd070dd1e0866f6915e09..e1848d0ed5a526e7d12739b8e443432ba81a651c 100644
--- a/proto/perxis/items/items.proto
+++ b/proto/perxis/items/items.proto
@@ -1,3 +1,11 @@
+/**
+ * # Items
+ *
+ * API Сервиса работы с пользовательским записями (Items)
+ *
+ * Предоставляет доступ к записям пользовательских коллекций
+ *
+ */
 syntax = "proto3";
 
 import "google/protobuf/empty.proto";
@@ -10,8 +18,8 @@ option go_package = "github.com/perxteam/perxis/proto/items;items";
 package content.items;
 
 message Error {
-	string message = 1;
-	string field = 2;
+	string message = 1; // Сообщение об ошибке
+	string field = 2; // Поле в котором произошла ошибка
 
 }
 
@@ -27,6 +35,9 @@ message ModificationError {
   repeated Error errors = 2;
 }
 
+/**
+ * Пользовательская запись
+ */
 message Item {
   enum State {
     DRAFT = 0;
@@ -39,20 +50,42 @@ message Item {
   string env_id = 3;
   string collection_id = 4;
   State state = 5;
-  google.protobuf.Timestamp created_at = 6;
-  string created_by = 7;
-  google.protobuf.Struct data = 8;
-  map<string, google.protobuf.Struct> translations = 9;
-  string revision_id = 10;
-  google.protobuf.Timestamp published_at = 11;
-  string published_by = 12;
-  google.protobuf.Timestamp archived_at = 13;
-  string archived_by = 14;
+  google.protobuf.Timestamp created_rev_at = 6; // дата создания текущей ревизии
+  string created_by = 7;                        // id пользователя создавшего первую ревизию
+  google.protobuf.Timestamp created_at = 8;     // дата создания первой ревизии
+  string updated_by = 9;                       // id пользователя обновившего текущую ревизию
+  google.protobuf.Timestamp updated_at = 10;     // дата обновления текущей ревизии
+  google.protobuf.Struct data = 11;
+  map<string, google.protobuf.Struct> translations = 12;
+  string revision_id = 13;
+  google.protobuf.Timestamp published_at = 14;
+  string published_by = 15;
+  google.protobuf.Timestamp archived_at = 16;
+  string archived_by = 17;
+  string locale = 18;
 }
 
 message Filter {
-  repeated string id = 1;
-  repeated common.Filter data = 2;
+  repeated string id = 1; // Список ID записей кото
+  repeated common.Filter data = 2; // Список фильтров
+  repeated string q = 3; // Список выражений для фильтрации
+}
+
+message FindOptions {
+  common.FindOptions options = 2;
+}
+
+message GetPublishedOptions {
+  string locale_id = 1;
+}
+
+message FindPublishedOptions {
+  common.FindOptions options = 2;
+  string locale_id = 3;
+}
+
+message FindArchivedOptions {
+  common.FindOptions options = 2;
 }
 
 message CreateRequest {
@@ -62,6 +95,15 @@ message CreateResponse {
   Item created = 1;
 }
 
+message IntrospectRequest {
+  Item item = 1;
+}
+message IntrospectResponse {
+  Item item = 1;
+  string schema = 2;
+  repeated common.Error.BadRequest.FieldViolation validation_errors = 3;
+}
+
 message GetRequest {
   string space_id = 1;
   string env_id = 2;
@@ -73,11 +115,11 @@ message GetResponse {
 }
 
 message FindRequest {
-  string space_id = 1;
-  string env_id = 2;
-  string collection_id = 3;
+  string space_id = 1; // ID Пространства
+  string env_id = 2; // ID окружения
+  string collection_id = 3; // ID коллекции
   Filter filter = 4;
-  common.FindOptions options = 5;
+  FindOptions options = 5; // Дополнительные параметры поиска
 }
 message FindResponse{
   repeated Item items = 1;
@@ -110,8 +152,8 @@ message GetPublishedRequest {
   string space_id = 1;
   string env_id = 2;
   string collection_id = 3;
-  string locale_id = 4;
   string item_id = 5;
+  GetPublishedOptions options = 10;
 }
 message GetPublishedResponse {
   Item item = 1;
@@ -121,9 +163,8 @@ message FindPublishedRequest {
   string space_id = 1;
   string env_id = 2;
   string collection_id = 3;
-  string locale_id = 4;
-  Filter filter = 5;
-  common.FindOptions options = 6;
+  Filter filter = 4;
+  FindPublishedOptions options = 10;
 }
 message FindPublishedResponse{
   repeated Item items = 1;
@@ -151,8 +192,11 @@ message ListRevisionsResponse {
   repeated Item items = 1;
 }
 
+/**
+ * Запрос на архивирование элемента
+ */
 message ArchiveRequest {
-  Item item = 1;
+  Item item = 1; // Элемент для архивации
 }
 
 message UnarchiveRequest {
@@ -166,18 +210,36 @@ message FindArchivedRequest {
   string space_id = 1;
   string env_id = 2;
   string collection_id = 3;
-  Filter filter = 5;
-  common.FindOptions options = 6;
+  Filter filter = 4;
+  FindArchivedOptions options = 6;
 }
 message FindArchivedResponse{
   repeated Item items = 1;
   int32 total = 2;
 }
 
+/**
+ * Сервис API элементов
+ */
 service Items {
-
+  /**
+   * Создать запись
+   */
   rpc Create(CreateRequest) returns(CreateResponse) {}
+
+  /**
+   * Валидация данных записи
+   */
+  rpc Introspect(IntrospectRequest) returns(IntrospectResponse) {}
+
+  /**
+   * Получение записи по идентификатору
+   */
   rpc Get(GetRequest) returns(GetResponse) {}
+
+  /**
+   * Поиск по текущим записям
+   */
   rpc Find(FindRequest) returns(FindResponse) {}
   rpc Update(UpdateRequest) returns(google.protobuf.Empty) {}
   rpc Delete(DeleteRequest) returns(google.protobuf.Empty) {}
diff --git a/proto/perxis/spaces/spaces.proto b/proto/perxis/spaces/spaces.proto
index 99bfe6f467b5c91d68768a5dec6b0ce633bcdb71..f68b5dfd8960364f486bd3194d9693aed55b1aee 100644
--- a/proto/perxis/spaces/spaces.proto
+++ b/proto/perxis/spaces/spaces.proto
@@ -28,6 +28,8 @@ enum State {
 
 message Config {
   repeated string features = 1;
+  bool allow_anonymous = 2;  // Разрешить доступ к пространству для неавторизованных пользователей
+  bool allow_any_authorized = 3;     // Разрешить доступ к пространству для любых авторизованных пользователей
 }
 
 message CreateRequest {
diff --git a/proto/perxis/status/status.proto b/proto/perxis/status/status.proto
new file mode 100644
index 0000000000000000000000000000000000000000..8fca6ab22d9e418c3f09d365d1e70ee8030f301e
--- /dev/null
+++ b/proto/perxis/status/status.proto
@@ -0,0 +1,90 @@
+// Copyright (c) 2015, Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+
+package google.rpc;
+
+import "google/protobuf/any.proto";
+
+option java_multiple_files = true;
+option java_outer_classname = "StatusProto";
+option java_package = "com.google.rpc";
+
+
+// The `Status` type defines a logical error model that is suitable for different
+// programming environments, including REST APIs and RPC APIs. It is used by
+// [gRPC](https://github.com/grpc). The error model is designed to be:
+//
+// - Simple to use and understand for most users
+// - Flexible enough to meet unexpected needs
+//
+// # Overview
+//
+// The `Status` message contains three pieces of data: error code, error message,
+// and error details. The error code should be an enum value of
+// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed.  The
+// error message should be a developer-facing English message that helps
+// developers *understand* and *resolve* the error. If a localized user-facing
+// error message is needed, put the localized message in the error details or
+// localize it in the client. The optional error details may contain arbitrary
+// information about the error. There is a predefined set of error detail types
+// in the package `google.rpc` which can be used for common error conditions.
+//
+// # Language mapping
+//
+// The `Status` message is the logical representation of the error model, but it
+// is not necessarily the actual wire format. When the `Status` message is
+// exposed in different client libraries and different wire protocols, it can be
+// mapped differently. For example, it will likely be mapped to some exceptions
+// in Java, but more likely mapped to some error codes in C.
+//
+// # Other uses
+//
+// The error model and the `Status` message can be used in a variety of
+// environments, either with or without APIs, to provide a
+// consistent developer experience across different environments.
+//
+// Example uses of this error model include:
+//
+// - Partial errors. If a service needs to return partial errors to the client,
+//     it may embed the `Status` in the normal response to indicate the partial
+//     errors.
+//
+// - Workflow errors. A typical workflow has multiple steps. Each step may
+//     have a `Status` message for error reporting purpose.
+//
+// - Batch operations. If a client uses batch request and batch response, the
+//     `Status` message should be used directly inside batch response, one for
+//     each error sub-response.
+//
+// - Asynchronous operations. If an API call embeds asynchronous operation
+//     results in its response, the status of those operations should be
+//     represented directly using the `Status` message.
+//
+// - Logging. If some API errors are stored in logs, the message `Status` could
+//     be used directly after any stripping needed for security/privacy reasons.
+message Status {
+  // The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
+  int32 code = 1;
+
+  // A developer-facing error message, which should be in English. Any
+  // user-facing error message should be localized and sent in the
+  // [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
+  string message = 2;
+
+  // A list of messages that carry the error details.  There will be a
+  // common set of message types for APIs to use.
+  repeated google.protobuf.Any details = 3;
+}
diff --git a/requirements.txt b/requirements.txt
index 3d4f799ef8bcb08f9dacbaa159009e6213cd2fc0..59ba16f3ddd274e6f4e7fafcfca706412244ebdd 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,11 +1,11 @@
-certifi==2020.12.5
+certifi==2021.5.30
 chardet==4.0.0
-grpcio==1.38.0
-idna==2.10
-oauthlib==3.1.0
-protobuf==3.17.1
+grpcio==1.39.0
+idna==3.2
+oauthlib==3.1.1
+protobuf==3.17.3
 PyJWT==2.1.0
-requests==2.25.1
+requests==2.26.0
 requests-oauthlib==1.3.0
-six==1.15.0
-urllib3==1.26.3
+six==1.16.0
+urllib3==1.26.6