Repository: weaviate/weaviate
Pull request #3181 (2023-06-28 13:32:10)

Add tenant to object and batchReference
### What's being changed:

- Adds tenant to the object struct and removes the extra tenant parameter from all rest calls where it makes sense (eg where we send an object)
- Allows batches (objects and references) with multiple tenants inside
- Simplifies the UX. Instead of using a property entry as tenant it is stored seperately.

to mark a class as MMT simply do 
```
	testClass := models.Class{
		Class: "MultiTenantClass",
		MultiTenancyConfig: &models.MultiTenancyConfig{
			Enabled: true,
		},
}

```
add tenant to class:
```
tenants = &models.Tenant{Name: "tenant"}
```

and create your objects as
```
			ID:    "0927a1e0-398e-4e76-91fb-04a7a8f0405c",
			Class: className,
			TenantName: "tenant",
```

and you're done

### Review checklist

- [ ] Documentation has been updated, if necessary. Link to changed documentation:
- [ ] Chaos pipeline run or not necessary. Link to pipeline:
- [ ] All new code is covered by tests where it is reasonable.
- [ ] Performance tests have been run or not necessary.


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate) Report
Patch coverage: **`75.25`**% and project coverage change: **`+0.03`** :tada:
> Comparison is base [(`d587c8d`)](https://app.codecov.io/gh/weaviate/weaviate/commit/d587c8d08ffe2273f573b7148be642afe8acb6a4?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate) 64.57% compared to head [(`9b25c24`)](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate) 64.60%.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##           master    #3181      +/-   ##
==========================================
+ Coverage   64.57%   64.60%   +0.03%     
==========================================
  Files         681      680       -1     
  Lines       70949    70987      +38     
==========================================
+ Hits        45816    45863      +47     
+ Misses      22281    22272       -9     
  Partials     2852     2852              
```


| [Impacted Files](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate) | Coverage Δ | |
|---|---|---|
| [.../handlers/graphql/local/aggregate/multi\_tenancy.go](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate#diff-YWRhcHRlcnMvaGFuZGxlcnMvZ3JhcGhxbC9sb2NhbC9hZ2dyZWdhdGUvbXVsdGlfdGVuYW5jeS5nbw==) | `20.00% <0.00%> (-13.34%)` | :arrow_down: |
| [...apters/handlers/graphql/local/get/multi\_tenancy.go](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate#diff-YWRhcHRlcnMvaGFuZGxlcnMvZ3JhcGhxbC9sb2NhbC9nZXQvbXVsdGlfdGVuYW5jeS5nbw==) | `27.27% <0.00%> (-6.07%)` | :arrow_down: |
| [adapters/handlers/rest/handlers\_batch\_objects.go](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate#diff-YWRhcHRlcnMvaGFuZGxlcnMvcmVzdC9oYW5kbGVyc19iYXRjaF9vYmplY3RzLmdv) | `0.00% <0.00%> (ø)` | |
| [adapters/handlers/rest/handlers\_schema.go](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate#diff-YWRhcHRlcnMvaGFuZGxlcnMvcmVzdC9oYW5kbGVyc19zY2hlbWEuZ28=) | `0.00% <0.00%> (ø)` | |
| [adapters/repos/db/vector/hnsw/config\_update.go](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate#diff-YWRhcHRlcnMvcmVwb3MvZGIvdmVjdG9yL2huc3cvY29uZmlnX3VwZGF0ZS5nbw==) | `27.84% <0.00%> (+1.96%)` | :arrow_up: |
| [adapters/repos/db/vector/hnsw/startup.go](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate#diff-YWRhcHRlcnMvcmVwb3MvZGIvdmVjdG9yL2huc3cvc3RhcnR1cC5nbw==) | `55.70% <0.00%> (+0.37%)` | :arrow_up: |
| [.../text2vec-cohere/additional/projector/projector.go](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate#diff-bW9kdWxlcy90ZXh0MnZlYy1jb2hlcmUvYWRkaXRpb25hbC9wcm9qZWN0b3IvcHJvamVjdG9yLmdv) | `57.81% <ø> (ø)` | |
| [...ec-contextionary/additional/projector/projector.go](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate#diff-bW9kdWxlcy90ZXh0MnZlYy1jb250ZXh0aW9uYXJ5L2FkZGl0aW9uYWwvcHJvamVjdG9yL3Byb2plY3Rvci5nbw==) | `37.37% <ø> (ø)` | |
| [...xt2vec-contextionary/additional/sempath/builder.go](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate#diff-bW9kdWxlcy90ZXh0MnZlYy1jb250ZXh0aW9uYXJ5L2FkZGl0aW9uYWwvc2VtcGF0aC9idWlsZGVyLmdv) | `0.00% <ø> (ø)` | |
| [...2vec-huggingface/additional/projector/projector.go](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate#diff-bW9kdWxlcy90ZXh0MnZlYy1odWdnaW5nZmFjZS9hZGRpdGlvbmFsL3Byb2plY3Rvci9wcm9qZWN0b3IuZ28=) | `57.81% <ø> (ø)` | |
| ... and [33 more](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate) | |

... and [9 files with indirect coverage changes](https://app.codecov.io/gh/weaviate/weaviate/pull/3181/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate)


</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/weaviate/weaviate/pull/3181?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate).   
:loudspeaker: Do you have feedback about the report comment? [Let us know in this issue](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=weaviate).


Patch:
diff --git a/adapters/handlers/graphql/local/aggregate/multi_tenancy.go b/adapters/handlers/graphql/local/aggregate/multi_tenancy.go
index 62349b27b1..77aee4b87b 100644
--- a/adapters/handlers/graphql/local/aggregate/multi_tenancy.go
+++ b/adapters/handlers/graphql/local/aggregate/multi_tenancy.go
@@ -18,9 +18,7 @@ import (
 )
 
 func multiTenancyEnabled(class *models.Class) bool {
-	if class.MultiTenancyConfig != nil &&
-		class.MultiTenancyConfig.Enabled &&
-		class.MultiTenancyConfig.TenantKey != "" {
+	if class.MultiTenancyConfig != nil && class.MultiTenancyConfig.Enabled {
 		return true
 	}
 	return false
diff --git a/adapters/handlers/graphql/local/get/multi_tenancy.go b/adapters/handlers/graphql/local/get/multi_tenancy.go
index 81ff47a27b..f2c08d1889 100644
--- a/adapters/handlers/graphql/local/get/multi_tenancy.go
+++ b/adapters/handlers/graphql/local/get/multi_tenancy.go
@@ -19,8 +19,7 @@ import (
 
 func multiTenancyEnabled(class *models.Class) bool {
 	if class.MultiTenancyConfig != nil &&
-		class.MultiTenancyConfig.Enabled &&
-		class.MultiTenancyConfig.TenantKey != "" {
+		class.MultiTenancyConfig.Enabled {
 		return true
 	}
 	return false
diff --git a/adapters/handlers/rest/embedded_spec.go b/adapters/handlers/rest/embedded_spec.go
index 7a8c0bc8b2..0684dd3fa1 100644
--- a/adapters/handlers/rest/embedded_spec.go
+++ b/adapters/handlers/rest/embedded_spec.go
@@ -437,9 +437,6 @@ func init() {
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -576,9 +573,6 @@ func init() {
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -1076,9 +1070,6 @@ func init() {
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -1280,9 +1271,6 @@ func init() {
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -1479,9 +1467,6 @@ func init() {
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -1873,9 +1858,6 @@ func init() {
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -2043,9 +2025,6 @@ func init() {
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -3188,6 +3167,10 @@ func init() {
           "format": "uri",
           "example": "weaviate://localhost/Zoo/a5d09582-4239-4702-81c9-92a6e0122bb4/hasAnimals"
         },
+        "tenantName": {
+          "description": "Name of the reference tenant.",
+          "type": "string"
+        },
         "to": {
           "description": "Short-form URI to point to the cross-ref. Should be in the form of weaviate://localhost/\u003cuuid\u003e for the example of a local cross-ref to an object",
           "type": "string",
@@ -3780,10 +3763,6 @@ func init() {
         "enabled": {
           "description": "Whether or not multi-tenancy is enabled for this class",
           "type": "boolean"
-        },
-        "tenantKey": {
-          "description": "The class property which is used to separate tenants",
-          "type": "string"
         }
       }
     },
@@ -3911,6 +3890,10 @@ func init() {
         "properties": {
           "$ref": "#/definitions/PropertySchema"
         },
+        "tenantName": {
+          "description": "Name of the Objects tenant.",
+          "type": "string"
+        },
         "vector": {
           "description": "This object's position in the Contextionary vector space. Read-only if using a vectorizer other than 'none'. Writable and required if using 'none' as vectorizer.",
           "$ref": "#/definitions/C11yVector"
@@ -5036,12 +5019,6 @@ func init() {
             "description": "Determines how many replicas must acknowledge a request before it is considered successful",
             "name": "consistency_level",
             "in": "query"
-          },
-          {
-            "type": "string",
-            "description": "Specifies the tenant in a request targeting a multi-tenant class",
-            "name": "tenant_key",
-            "in": "query"
           }
         ],
         "responses": {
@@ -5187,12 +5164,6 @@ func init() {
             "description": "Determines how many replicas must acknowledge a request before it is considered successful",
             "name": "consistency_level",
             "in": "query"
-          },
-          {
-            "type": "string",
-            "description": "Specifies the tenant in a request targeting a multi-tenant class",
-            "name": "tenant_key",
-            "in": "query"
           }
         ],
         "responses": {
@@ -5717,12 +5688,6 @@ func init() {
             "description": "Determines how many replicas must acknowledge a request before it is considered successful",
             "name": "consistency_level",
             "in": "query"
-          },
-          {
-            "type": "string",
-            "description": "Specifies the tenant in a request targeting a multi-tenant class",
-            "name": "tenant_key",
-            "in": "query"
           }
         ],
         "responses": {
@@ -5939,12 +5904,6 @@ func init() {
             "description": "Determines how many replicas must acknowledge a request before it is considered successful",
             "name": "consistency_level",
             "in": "query"
-          },
-          {
-            "type": "string",
-            "description": "Specifies the tenant in a request targeting a multi-tenant class",
-            "name": "tenant_key",
-            "in": "query"
           }
         ],
         "responses": {
@@ -6156,12 +6115,6 @@ func init() {
             "description": "Determines how many replicas must acknowledge a request before it is considered successful",
             "name": "consistency_level",
             "in": "query"
-          },
-          {
-            "type": "string",
-            "description": "Specifies the tenant in a request targeting a multi-tenant class",
-            "name": "tenant_key",
-            "in": "query"
           }
         ],
         "responses": {
@@ -6577,12 +6530,6 @@ func init() {
             "description": "Determines how many replicas must acknowledge a request before it is considered successful",
             "name": "consistency_level",
             "in": "query"
-          },
-          {
-            "type": "string",
-            "description": "Specifies the tenant in a request targeting a multi-tenant class",
-            "name": "tenant_key",
-            "in": "query"
           }
         ],
         "responses": {
@@ -6759,12 +6706,6 @@ func init() {
             "description": "Determines how many replicas must acknowledge a request before it is considered successful",
             "name": "consistency_level",
             "in": "query"
-          },
-          {
-            "type": "string",
-            "description": "Specifies the tenant in a request targeting a multi-tenant class",
-            "name": "tenant_key",
-            "in": "query"
           }
         ],
         "responses": {
@@ -7978,6 +7919,10 @@ func init() {
           "format": "uri",
           "example": "weaviate://localhost/Zoo/a5d09582-4239-4702-81c9-92a6e0122bb4/hasAnimals"
         },
+        "tenantName": {
+          "description": "Name of the reference tenant.",
+          "type": "string"
+        },
         "to": {
           "description": "Short-form URI to point to the cross-ref. Should be in the form of weaviate://localhost/\u003cuuid\u003e for the example of a local cross-ref to an object",
           "type": "string",
@@ -8658,10 +8603,6 @@ func init() {
         "enabled": {
           "description": "Whether or not multi-tenancy is enabled for this class",
           "type": "boolean"
-        },
-        "tenantKey": {
-          "description": "The class property which is used to separate tenants",
-          "type": "string"
         }
       }
     },
@@ -8789,6 +8730,10 @@ func init() {
         "properties": {
           "$ref": "#/definitions/PropertySchema"
         },
+        "tenantName": {
+          "description": "Name of the Objects tenant.",
+          "type": "string"
+        },
         "vector": {
           "description": "This object's position in the Contextionary vector space. Read-only if using a vectorizer other than 'none'. Writable and required if using 'none' as vectorizer.",
           "$ref": "#/definitions/C11yVector"
diff --git a/adapters/handlers/rest/handlers_batch_objects.go b/adapters/handlers/rest/handlers_batch_objects.go
index 2aa3bba866..6fc8302809 100644
--- a/adapters/handlers/rest/handlers_batch_objects.go
+++ b/adapters/handlers/rest/handlers_batch_objects.go
@@ -36,10 +36,8 @@ func (h *batchObjectHandlers) addObjects(params batch.BatchObjectsCreateParams,
 			WithPayload(errPayloadFromSingleErr(err))
 	}
 
-	tenantKey := getTenantKey(params.TenantKey)
-
 	objs, err := h.manager.AddObjects(params.HTTPRequest.Context(), principal,
-		params.Body.Objects, params.Body.Fields, repl, tenantKey)
+		params.Body.Objects, params.Body.Fields, repl)
 	if err != nil {
 		switch err.(type) {
 		case autherrs.Forbidden:
@@ -87,10 +85,7 @@ func (h *batchObjectHandlers) addReferences(params batch.BatchReferencesCreatePa
 			WithPayload(errPayloadFromSingleErr(err))
 	}
 
-	tenantKey := getTenantKey(params.TenantKey)
-
-	references, err := h.manager.AddReferences(
-		params.HTTPRequest.Context(), principal, params.Body, repl, tenantKey)
+	references, err := h.manager.AddReferences(params.HTTPRequest.Context(), principal, params.Body, repl)
 	if err != nil {
 		switch err.(type) {
 		case autherrs.Forbidden:
diff --git a/adapters/handlers/rest/handlers_objects.go b/adapters/handlers/rest/handlers_objects.go
index 557693022e..f211a44b0b 100644
--- a/adapters/handlers/rest/handlers_objects.go
+++ b/adapters/handlers/rest/handlers_objects.go
@@ -46,7 +46,7 @@ type ModulesProvider interface {
 
 type objectsManager interface {
 	AddObject(context.Context, *models.Principal, *models.Object,
-		*additional.ReplicationProperties, string) (*models.Object, error)
+		*additional.ReplicationProperties) (*models.Object, error)
 	ValidateObject(context.Context, *models.Principal,
 		*models.Object, *additional.ReplicationProperties) error
 	GetObject(context.Context, *models.Principal, string, strfmt.UUID,
@@ -54,7 +54,7 @@ type objectsManager interface {
 	DeleteObject(context.Context, *models.Principal, string,
 		strfmt.UUID, *additional.ReplicationProperties, string) error
 	UpdateObject(context.Context, *models.Principal, string, strfmt.UUID,
-		*models.Object, *additional.ReplicationProperties, string) (*models.Object, error)
+		*models.Object, *additional.ReplicationProperties) (*models.Object, error)
 	HeadObject(ctx context.Context, principal *models.Principal, class string, id strfmt.UUID,
 		repl *additional.ReplicationProperties, tenantKey string) (bool, *uco.Error)
 	GetObjects(context.Context, *models.Principal, *int64, *int64,
@@ -62,7 +62,7 @@ type objectsManager interface {
 	Query(ctx context.Context, principal *models.Principal,
 		params *uco.QueryParams) ([]*models.Object, *uco.Error)
 	MergeObject(context.Context, *models.Principal, *models.Object,
-		*additional.ReplicationProperties, string) *uco.Error
+		*additional.ReplicationProperties) *uco.Error
 	AddObjectReference(context.Context, *models.Principal, *uco.AddReferenceInput,
 		*additional.ReplicationProperties, string) *uco.Error
 	UpdateObjectReferences(context.Context, *models.Principal,
@@ -81,10 +81,8 @@ func (h *objectHandlers) addObject(params objects.ObjectsCreateParams,
 			WithPayload(errPayloadFromSingleErr(err))
 	}
 
-	tenantKey := getTenantKey(params.TenantKey)
-
 	object, err := h.manager.AddObject(params.HTTPRequest.Context(),
-		principal, params.Body, repl, tenantKey)
+		principal, params.Body, repl)
 	if err != nil {
 		if errors.As(err, &uco.ErrInvalidUserInput{}) {
 			return objects.NewObjectsCreateUnprocessableEntity().
@@ -314,10 +312,8 @@ func (h *objectHandlers) updateObject(params objects.ObjectsClassPutParams,
 			WithPayload(errPayloadFromSingleErr(err))
 	}
 
-	tenantKey := getTenantKey(params.TenantKey)
-
 	object, err := h.manager.UpdateObject(params.HTTPRequest.Context(),
-		principal, params.ClassName, params.ID, params.Body, repl, tenantKey)
+		principal, params.ClassName, params.ID, params.Body, repl)
 	if err != nil {
 		if errors.As(err, &uco.ErrInvalidUserInput{}) {
 			return objects.NewObjectsClassPutUnprocessableEntity().
@@ -380,9 +376,7 @@ func (h *objectHandlers) patchObject(params objects.ObjectsClassPatchParams, pri
 			WithPayload(errPayloadFromSingleErr(err))
 	}
 
-	tenantKey := getTenantKey(params.TenantKey)
-
-	objErr := h.manager.MergeObject(params.HTTPRequest.Context(), principal, updates, repl, tenantKey)
+	objErr := h.manager.MergeObject(params.HTTPRequest.Context(), principal, updates, repl)
 	if objErr != nil {
 		switch {
 		case objErr.NotFound():
diff --git a/adapters/handlers/rest/operations/batch/batch_objects_create_parameters.go b/adapters/handlers/rest/operations/batch/batch_objects_create_parameters.go
index a10e3705a4..92606465e6 100644
--- a/adapters/handlers/rest/operations/batch/batch_objects_create_parameters.go
+++ b/adapters/handlers/rest/operations/batch/batch_objects_create_parameters.go
@@ -53,10 +53,6 @@ type BatchObjectsCreateParams struct {
 	  In: query
 	*/
 	ConsistencyLevel *string
-	/*Specifies the tenant in a request targeting a multi-tenant class
-	  In: query
-	*/
-	TenantKey *string
 }
 
 // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
@@ -102,11 +98,6 @@ func (o *BatchObjectsCreateParams) BindRequest(r *http.Request, route *middlewar
 	if err := o.bindConsistencyLevel(qConsistencyLevel, qhkConsistencyLevel, route.Formats); err != nil {
 		res = append(res, err)
 	}
-
-	qTenantKey, qhkTenantKey, _ := qs.GetOK("tenant_key")
-	if err := o.bindTenantKey(qTenantKey, qhkTenantKey, route.Formats); err != nil {
-		res = append(res, err)
-	}
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
@@ -130,21 +121,3 @@ func (o *BatchObjectsCreateParams) bindConsistencyLevel(rawData []string, hasKey
 
 	return nil
 }
-
-// bindTenantKey binds and validates parameter TenantKey from query.
-func (o *BatchObjectsCreateParams) bindTenantKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
-	var raw string
-	if len(rawData) > 0 {
-		raw = rawData[len(rawData)-1]
-	}
-
-	// Required: false
-	// AllowEmptyValue: false
-
-	if raw == "" { // empty values pass all other validations
-		return nil
-	}
-	o.TenantKey = &raw
-
-	return nil
-}
diff --git a/adapters/handlers/rest/operations/batch/batch_objects_create_urlbuilder.go b/adapters/handlers/rest/operations/batch/batch_objects_create_urlbuilder.go
index c167590cfb..fba49c20e0 100644
--- a/adapters/handlers/rest/operations/batch/batch_objects_create_urlbuilder.go
+++ b/adapters/handlers/rest/operations/batch/batch_objects_create_urlbuilder.go
@@ -25,7 +25,6 @@ import (
 // BatchObjectsCreateURL generates an URL for the batch objects create operation
 type BatchObjectsCreateURL struct {
 	ConsistencyLevel *string
-	TenantKey        *string
 
 	_basePath string
 	// avoid unkeyed usage
@@ -69,14 +68,6 @@ func (o *BatchObjectsCreateURL) Build() (*url.URL, error) {
 		qs.Set("consistency_level", consistencyLevelQ)
 	}
 
-	var tenantKeyQ string
-	if o.TenantKey != nil {
-		tenantKeyQ = *o.TenantKey
-	}
-	if tenantKeyQ != "" {
-		qs.Set("tenant_key", tenantKeyQ)
-	}
-
 	_result.RawQuery = qs.Encode()
 
 	return &_result, nil
diff --git a/adapters/handlers/rest/operations/batch/batch_references_create_parameters.go b/adapters/handlers/rest/operations/batch/batch_references_create_parameters.go
index 1fe7f95e91..570d4b4d09 100644
--- a/adapters/handlers/rest/operations/batch/batch_references_create_parameters.go
+++ b/adapters/handlers/rest/operations/batch/batch_references_create_parameters.go
@@ -54,10 +54,6 @@ type BatchReferencesCreateParams struct {
 	  In: query
 	*/
 	ConsistencyLevel *string
-	/*Specifies the tenant in a request targeting a multi-tenant class
-	  In: query
-	*/
-	TenantKey *string
 }
 
 // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
@@ -105,11 +101,6 @@ func (o *BatchReferencesCreateParams) BindRequest(r *http.Request, route *middle
 	if err := o.bindConsistencyLevel(qConsistencyLevel, qhkConsistencyLevel, route.Formats); err != nil {
 		res = append(res, err)
 	}
-
-	qTenantKey, qhkTenantKey, _ := qs.GetOK("tenant_key")
-	if err := o.bindTenantKey(qTenantKey, qhkTenantKey, route.Formats); err != nil {
-		res = append(res, err)
-	}
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
@@ -133,21 +124,3 @@ func (o *BatchReferencesCreateParams) bindConsistencyLevel(rawData []string, has
 
 	return nil
 }
-
-// bindTenantKey binds and validates parameter TenantKey from query.
-func (o *BatchReferencesCreateParams) bindTenantKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
-	var raw string
-	if len(rawData) > 0 {
-		raw = rawData[len(rawData)-1]
-	}
-
-	// Required: false
-	// AllowEmptyValue: false
-
-	if raw == "" { // empty values pass all other validations
-		return nil
-	}
-	o.TenantKey = &raw
-
-	return nil
-}
diff --git a/adapters/handlers/rest/operations/batch/batch_references_create_urlbuilder.go b/adapters/handlers/rest/operations/batch/batch_references_create_urlbuilder.go
index cb5621ab65..7c2d243be1 100644
--- a/adapters/handlers/rest/operations/batch/batch_references_create_urlbuilder.go
+++ b/adapters/handlers/rest/operations/batch/batch_references_create_urlbuilder.go
@@ -25,7 +25,6 @@ import (
 // BatchReferencesCreateURL generates an URL for the batch references create operation
 type BatchReferencesCreateURL struct {
 	ConsistencyLevel *string
-	TenantKey        *string
 
 	_basePath string
 	// avoid unkeyed usage
@@ -69,14 +68,6 @@ func (o *BatchReferencesCreateURL) Build() (*url.URL, error) {
 		qs.Set("consistency_level", consistencyLevelQ)
 	}
 
-	var tenantKeyQ string
-	if o.TenantKey != nil {
-		tenantKeyQ = *o.TenantKey
-	}
-	if tenantKeyQ != "" {
-		qs.Set("tenant_key", tenantKeyQ)
-	}
-
 	_result.RawQuery = qs.Encode()
 
 	return &_result, nil
diff --git a/adapters/handlers/rest/operations/objects/objects_class_patch_parameters.go b/adapters/handlers/rest/operations/objects/objects_class_patch_parameters.go
index 1556f1575c..3a83f497a1 100644
--- a/adapters/handlers/rest/operations/objects/objects_class_patch_parameters.go
+++ b/adapters/handlers/rest/operations/objects/objects_class_patch_parameters.go
@@ -63,10 +63,6 @@ type ObjectsClassPatchParams struct {
 	  In: path
 	*/
 	ID strfmt.UUID
-	/*Specifies the tenant in a request targeting a multi-tenant class
-	  In: query
-	*/
-	TenantKey *string
 }
 
 // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
@@ -116,11 +112,6 @@ func (o *ObjectsClassPatchParams) BindRequest(r *http.Request, route *middleware
 	if err := o.bindID(rID, rhkID, route.Formats); err != nil {
 		res = append(res, err)
 	}
-
-	qTenantKey, qhkTenantKey, _ := qs.GetOK("tenant_key")
-	if err := o.bindTenantKey(qTenantKey, qhkTenantKey, route.Formats); err != nil {
-		res = append(res, err)
-	}
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
@@ -191,21 +182,3 @@ func (o *ObjectsClassPatchParams) validateID(formats strfmt.Registry) error {
 	}
 	return nil
 }
-
-// bindTenantKey binds and validates parameter TenantKey from query.
-func (o *ObjectsClassPatchParams) bindTenantKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
-	var raw string
-	if len(rawData) > 0 {
-		raw = rawData[len(rawData)-1]
-	}
-
-	// Required: false
-	// AllowEmptyValue: false
-
-	if raw == "" { // empty values pass all other validations
-		return nil
-	}
-	o.TenantKey = &raw
-
-	return nil
-}
diff --git a/adapters/handlers/rest/operations/objects/objects_class_patch_urlbuilder.go b/adapters/handlers/rest/operations/objects/objects_class_patch_urlbuilder.go
index ae28273971..138fad08bb 100644
--- a/adapters/handlers/rest/operations/objects/objects_class_patch_urlbuilder.go
+++ b/adapters/handlers/rest/operations/objects/objects_class_patch_urlbuilder.go
@@ -31,7 +31,6 @@ type ObjectsClassPatchURL struct {
 	ID        strfmt.UUID
 
 	ConsistencyLevel *string
-	TenantKey        *string
 
 	_basePath string
 	// avoid unkeyed usage
@@ -89,14 +88,6 @@ func (o *ObjectsClassPatchURL) Build() (*url.URL, error) {
 		qs.Set("consistency_level", consistencyLevelQ)
 	}
 
-	var tenantKeyQ string
-	if o.TenantKey != nil {
-		tenantKeyQ = *o.TenantKey
-	}
-	if tenantKeyQ != "" {
-		qs.Set("tenant_key", tenantKeyQ)
-	}
-
 	_result.RawQuery = qs.Encode()
 
 	return &_result, nil
diff --git a/adapters/handlers/rest/operations/objects/objects_class_put_parameters.go b/adapters/handlers/rest/operations/objects/objects_class_put_parameters.go
index 3d6e10c3ec..264398ecbf 100644
--- a/adapters/handlers/rest/operations/objects/objects_class_put_parameters.go
+++ b/adapters/handlers/rest/operations/objects/objects_class_put_parameters.go
@@ -65,10 +65,6 @@ type ObjectsClassPutParams struct {
 	  In: path
 	*/
 	ID strfmt.UUID
-	/*Specifies the tenant in a request targeting a multi-tenant class
-	  In: query
-	*/
-	TenantKey *string
 }
 
 // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
@@ -124,11 +120,6 @@ func (o *ObjectsClassPutParams) BindRequest(r *http.Request, route *middleware.M
 	if err := o.bindID(rID, rhkID, route.Formats); err != nil {
 		res = append(res, err)
 	}
-
-	qTenantKey, qhkTenantKey, _ := qs.GetOK("tenant_key")
-	if err := o.bindTenantKey(qTenantKey, qhkTenantKey, route.Formats); err != nil {
-		res = append(res, err)
-	}
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
@@ -199,21 +190,3 @@ func (o *ObjectsClassPutParams) validateID(formats strfmt.Registry) error {
 	}
 	return nil
 }
-
-// bindTenantKey binds and validates parameter TenantKey from query.
-func (o *ObjectsClassPutParams) bindTenantKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
-	var raw string
-	if len(rawData) > 0 {
-		raw = rawData[len(rawData)-1]
-	}
-
-	// Required: false
-	// AllowEmptyValue: false
-
-	if raw == "" { // empty values pass all other validations
-		return nil
-	}
-	o.TenantKey = &raw
-
-	return nil
-}
diff --git a/adapters/handlers/rest/operations/objects/objects_class_put_urlbuilder.go b/adapters/handlers/rest/operations/objects/objects_class_put_urlbuilder.go
index 851b2bfdbc..1cd2ab7218 100644
--- a/adapters/handlers/rest/operations/objects/objects_class_put_urlbuilder.go
+++ b/adapters/handlers/rest/operations/objects/objects_class_put_urlbuilder.go
@@ -31,7 +31,6 @@ type ObjectsClassPutURL struct {
 	ID        strfmt.UUID
 
 	ConsistencyLevel *string
-	TenantKey        *string
 
 	_basePath string
 	// avoid unkeyed usage
@@ -89,14 +88,6 @@ func (o *ObjectsClassPutURL) Build() (*url.URL, error) {
 		qs.Set("consistency_level", consistencyLevelQ)
 	}
 
-	var tenantKeyQ string
-	if o.TenantKey != nil {
-		tenantKeyQ = *o.TenantKey
-	}
-	if tenantKeyQ != "" {
-		qs.Set("tenant_key", tenantKeyQ)
-	}
-
 	_result.RawQuery = qs.Encode()
 
 	return &_result, nil
diff --git a/adapters/handlers/rest/operations/objects/objects_create_parameters.go b/adapters/handlers/rest/operations/objects/objects_create_parameters.go
index 78f184c3f2..110a3027ce 100644
--- a/adapters/handlers/rest/operations/objects/objects_create_parameters.go
+++ b/adapters/handlers/rest/operations/objects/objects_create_parameters.go
@@ -55,10 +55,6 @@ type ObjectsCreateParams struct {
 	  In: query
 	*/
 	ConsistencyLevel *string
-	/*Specifies the tenant in a request targeting a multi-tenant class
-	  In: query
-	*/
-	TenantKey *string
 }
 
 // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
@@ -104,11 +100,6 @@ func (o *ObjectsCreateParams) BindRequest(r *http.Request, route *middleware.Mat
 	if err := o.bindConsistencyLevel(qConsistencyLevel, qhkConsistencyLevel, route.Formats); err != nil {
 		res = append(res, err)
 	}
-
-	qTenantKey, qhkTenantKey, _ := qs.GetOK("tenant_key")
-	if err := o.bindTenantKey(qTenantKey, qhkTenantKey, route.Formats); err != nil {
-		res = append(res, err)
-	}
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
@@ -132,21 +123,3 @@ func (o *ObjectsCreateParams) bindConsistencyLevel(rawData []string, hasKey bool
 
 	return nil
 }
-
-// bindTenantKey binds and validates parameter TenantKey from query.
-func (o *ObjectsCreateParams) bindTenantKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
-	var raw string
-	if len(rawData) > 0 {
-		raw = rawData[len(rawData)-1]
-	}
-
-	// Required: false
-	// AllowEmptyValue: false
-
-	if raw == "" { // empty values pass all other validations
-		return nil
-	}
-	o.TenantKey = &raw
-
-	return nil
-}
diff --git a/adapters/handlers/rest/operations/objects/objects_create_urlbuilder.go b/adapters/handlers/rest/operations/objects/objects_create_urlbuilder.go
index f5dbcbe678..15533da9f7 100644
--- a/adapters/handlers/rest/operations/objects/objects_create_urlbuilder.go
+++ b/adapters/handlers/rest/operations/objects/objects_create_urlbuilder.go
@@ -25,7 +25,6 @@ import (
 // ObjectsCreateURL generates an URL for the objects create operation
 type ObjectsCreateURL struct {
 	ConsistencyLevel *string
-	TenantKey        *string
 
 	_basePath string
 	// avoid unkeyed usage
@@ -69,14 +68,6 @@ func (o *ObjectsCreateURL) Build() (*url.URL, error) {
 		qs.Set("consistency_level", consistencyLevelQ)
 	}
 
-	var tenantKeyQ string
-	if o.TenantKey != nil {
-		tenantKeyQ = *o.TenantKey
-	}
-	if tenantKeyQ != "" {
-		qs.Set("tenant_key", tenantKeyQ)
-	}
-
 	_result.RawQuery = qs.Encode()
 
 	return &_result, nil
diff --git a/adapters/handlers/rest/operations/objects/objects_patch_parameters.go b/adapters/handlers/rest/operations/objects/objects_patch_parameters.go
index 3ca3101875..ea1c15da44 100644
--- a/adapters/handlers/rest/operations/objects/objects_patch_parameters.go
+++ b/adapters/handlers/rest/operations/objects/objects_patch_parameters.go
@@ -58,10 +58,6 @@ type ObjectsPatchParams struct {
 	  In: path
 	*/
 	ID strfmt.UUID
-	/*Specifies the tenant in a request targeting a multi-tenant class
-	  In: query
-	*/
-	TenantKey *string
 }
 
 // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
@@ -106,11 +102,6 @@ func (o *ObjectsPatchParams) BindRequest(r *http.Request, route *middleware.Matc
 	if err := o.bindID(rID, rhkID, route.Formats); err != nil {
 		res = append(res, err)
 	}
-
-	qTenantKey, qhkTenantKey, _ := qs.GetOK("tenant_key")
-	if err := o.bindTenantKey(qTenantKey, qhkTenantKey, route.Formats); err != nil {
-		res = append(res, err)
-	}
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
@@ -167,21 +158,3 @@ func (o *ObjectsPatchParams) validateID(formats strfmt.Registry) error {
 	}
 	return nil
 }
-
-// bindTenantKey binds and validates parameter TenantKey from query.
-func (o *ObjectsPatchParams) bindTenantKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
-	var raw string
-	if len(rawData) > 0 {
-		raw = rawData[len(rawData)-1]
-	}
-
-	// Required: false
-	// AllowEmptyValue: false
-
-	if raw == "" { // empty values pass all other validations
-		return nil
-	}
-	o.TenantKey = &raw
-
-	return nil
-}
diff --git a/adapters/handlers/rest/operations/objects/objects_patch_urlbuilder.go b/adapters/handlers/rest/operations/objects/objects_patch_urlbuilder.go
index 411532381d..8fb9e1b0dc 100644
--- a/adapters/handlers/rest/operations/objects/objects_patch_urlbuilder.go
+++ b/adapters/handlers/rest/operations/objects/objects_patch_urlbuilder.go
@@ -30,7 +30,6 @@ type ObjectsPatchURL struct {
 	ID strfmt.UUID
 
 	ConsistencyLevel *string
-	TenantKey        *string
 
 	_basePath string
 	// avoid unkeyed usage
@@ -81,14 +80,6 @@ func (o *ObjectsPatchURL) Build() (*url.URL, error) {
 		qs.Set("consistency_level", consistencyLevelQ)
 	}
 
-	var tenantKeyQ string
-	if o.TenantKey != nil {
-		tenantKeyQ = *o.TenantKey
-	}
-	if tenantKeyQ != "" {
-		qs.Set("tenant_key", tenantKeyQ)
-	}
-
 	_result.RawQuery = qs.Encode()
 
 	return &_result, nil
diff --git a/adapters/handlers/rest/operations/objects/objects_update_parameters.go b/adapters/handlers/rest/operations/objects/objects_update_parameters.go
index 0060f930ad..ba2d179516 100644
--- a/adapters/handlers/rest/operations/objects/objects_update_parameters.go
+++ b/adapters/handlers/rest/operations/objects/objects_update_parameters.go
@@ -60,10 +60,6 @@ type ObjectsUpdateParams struct {
 	  In: path
 	*/
 	ID strfmt.UUID
-	/*Specifies the tenant in a request targeting a multi-tenant class
-	  In: query
-	*/
-	TenantKey *string
 }
 
 // BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
@@ -114,11 +110,6 @@ func (o *ObjectsUpdateParams) BindRequest(r *http.Request, route *middleware.Mat
 	if err := o.bindID(rID, rhkID, route.Formats); err != nil {
 		res = append(res, err)
 	}
-
-	qTenantKey, qhkTenantKey, _ := qs.GetOK("tenant_key")
-	if err := o.bindTenantKey(qTenantKey, qhkTenantKey, route.Formats); err != nil {
-		res = append(res, err)
-	}
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
@@ -175,21 +166,3 @@ func (o *ObjectsUpdateParams) validateID(formats strfmt.Registry) error {
 	}
 	return nil
 }
-
-// bindTenantKey binds and validates parameter TenantKey from query.
-func (o *ObjectsUpdateParams) bindTenantKey(rawData []string, hasKey bool, formats strfmt.Registry) error {
-	var raw string
-	if len(rawData) > 0 {
-		raw = rawData[len(rawData)-1]
-	}
-
-	// Required: false
-	// AllowEmptyValue: false
-
-	if raw == "" { // empty values pass all other validations
-		return nil
-	}
-	o.TenantKey = &raw
-
-	return nil
-}
diff --git a/adapters/handlers/rest/operations/objects/objects_update_urlbuilder.go b/adapters/handlers/rest/operations/objects/objects_update_urlbuilder.go
index 21a669d731..ea2ab05aab 100644
--- a/adapters/handlers/rest/operations/objects/objects_update_urlbuilder.go
+++ b/adapters/handlers/rest/operations/objects/objects_update_urlbuilder.go
@@ -30,7 +30,6 @@ type ObjectsUpdateURL struct {
 	ID strfmt.UUID
 
 	ConsistencyLevel *string
-	TenantKey        *string
 
 	_basePath string
 	// avoid unkeyed usage
@@ -81,14 +80,6 @@ func (o *ObjectsUpdateURL) Build() (*url.URL, error) {
 		qs.Set("consistency_level", consistencyLevelQ)
 	}
 
-	var tenantKeyQ string
-	if o.TenantKey != nil {
-		tenantKeyQ = *o.TenantKey
-	}
-	if tenantKeyQ != "" {
-		qs.Set("tenant_key", tenantKeyQ)
-	}
-
 	_result.RawQuery = qs.Encode()
 
 	return &_result, nil
diff --git a/adapters/repos/db/batch.go b/adapters/repos/db/batch.go
index e7cdc7c330..3c561bfe20 100644
--- a/adapters/repos/db/batch.go
+++ b/adapters/repos/db/batch.go
@@ -28,7 +28,7 @@ type batchQueue struct {
 }
 
 func (db *DB) BatchPutObjects(ctx context.Context, objs objects.BatchObjects,
-	repl *additional.ReplicationProperties, tenantKey string,
+	repl *additional.ReplicationProperties,
 ) (objects.BatchObjects, error) {
 	objectByClass := make(map[string]batchQueue)
 	indexByClass := make(map[string]*Index)
@@ -81,7 +81,7 @@ func (db *DB) BatchPutObjects(ctx context.Context, objs objects.BatchObjects,
 
 	for class, index := range indexByClass {
 		queue := objectByClass[class]
-		errs := index.putObjectBatch(ctx, queue.objects, repl, tenantKey)
+		errs := index.putObjectBatch(ctx, queue.objects, repl)
 		// remove index from map to skip releasing its lock in defer
 		indexByClass[class] = nil
 		index.dropIndex.RUnlock()
@@ -96,7 +96,7 @@ func (db *DB) BatchPutObjects(ctx context.Context, objs objects.BatchObjects,
 }
 
 func (db *DB) AddBatchReferences(ctx context.Context, references objects.BatchReferences,
-	repl *additional.ReplicationProperties, tenantKey string,
+	repl *additional.ReplicationProperties,
 ) (objects.BatchReferences, error) {
 	refByClass := make(map[schema.ClassName]objects.BatchReferences)
 	indexByClass := make(map[schema.ClassName]*Index)
@@ -138,7 +138,7 @@ func (db *DB) AddBatchReferences(ctx context.Context, references objects.BatchRe
 
 	for class, index := range indexByClass {
 		queue := refByClass[class]
-		errs := index.addReferencesBatch(ctx, queue, repl, tenantKey)
+		errs := index.addReferencesBatch(ctx, queue, repl)
 		// remove index from map to skip releasing its lock in defer
 		indexByClass[class] = nil
 		index.dropIndex.RUnlock()
@@ -160,9 +160,6 @@ func (db *DB) BatchDeleteObjects(ctx context.Context, params objects.BatchDelete
 	if idx == nil {
 		return objects.BatchDeleteResult{}, errors.Errorf("cannot find index for class %v", params.ClassName)
 	}
-	if err := idx.validateMultiTenancy(tenantKey, nil); err != nil {
-		return objects.BatchDeleteResult{}, err
-	}
 	// find all DocIDs in all shards that match the filter
 	shardDocIDs, err := idx.findDocIDs(ctx, params.Filters, tenantKey)
 	if err != nil {
diff --git a/adapters/repos/db/crud.go b/adapters/repos/db/crud.go
index e880dfc0e0..b05e21793e 100644
--- a/adapters/repos/db/crud.go
+++ b/adapters/repos/db/crud.go
@@ -31,7 +31,6 @@ import (
 
 func (db *DB) PutObject(ctx context.Context, obj *models.Object,
 	vector []float32, repl *additional.ReplicationProperties,
-	tenantKey string,
 ) error {
 	object := storobj.FromObject(obj, vector)
 	idx := db.GetIndex(object.Class())
@@ -39,7 +38,7 @@ func (db *DB) PutObject(ctx context.Context, obj *models.Object,
 		return fmt.Errorf("import into non-existing index for %s", object.Class())
 	}
 
-	if err := idx.putObject(ctx, object, repl, tenantKey); err != nil {
+	if err := idx.putObject(ctx, object, repl); err != nil {
 		return fmt.Errorf("import into index %s: %w", idx.ID(), err)
 	}
 
diff --git a/adapters/repos/db/index.go b/adapters/repos/db/index.go
index c5f9130965..af937a3b43 100644
--- a/adapters/repos/db/index.go
+++ b/adapters/repos/db/index.go
@@ -120,8 +120,6 @@ type Index struct {
 	invertedIndexConfig     schema.InvertedIndexConfig
 	invertedIndexConfigLock sync.Mutex
 
-	tenantKey string
-
 	// This lock should be used together with the db indexLock.
 	//
 	// The db indexlock locks the map that contains all indices against changes and should be used while iterating.
@@ -180,9 +178,6 @@ func NewIndex(ctx context.Context, config IndexConfig,
 		metrics:         NewMetrics(logger, promMetrics, config.ClassName.String(), "n/a"),
 		centralJobQueue: jobQueueCh,
 	}
-	if class != nil && class.MultiTenancyConfig != nil {
-		index.tenantKey = class.MultiTenancyConfig.TenantKey
-	}
 
 	if err := index.checkSingleShardMigration(shardState); err != nil {
 		return nil, errors.Wrap(err, "migrating sharding state from previous version")
@@ -340,6 +335,12 @@ func (i *Index) determineObjectShard(id strfmt.UUID, tenantKey string, ss *shard
 			return "", fmt.Errorf("cannot find sharding state for class %q", i.Config.ClassName.String())
 		}
 	}
+	if ss.PartitioningEnabled && tenantKey == "" {
+		return "", errors.New("object without tenantName for class with multi tenancy")
+	} else if !ss.PartitioningEnabled && tenantKey != "" {
+		return "", errors.New("object with tenantName for class without multi tenancy")
+	}
+
 	if tenantKey != "" {
 		return i.shardFromTenantKey(tenantKey, id, ss)
 	}
@@ -354,9 +355,9 @@ func (i *Index) shardFromTenantKey(tenantKey string, id strfmt.UUID, ss *shardin
 }
 
 func (i *Index) putObject(ctx context.Context, object *storobj.Object,
-	replProps *additional.ReplicationProperties, tenantKey string,
+	replProps *additional.ReplicationProperties,
 ) error {
-	if err := i.validateMultiTenancy(tenantKey, &object.Object); err != nil {
+	if err := i.validateMultiTenancy(object.Object.TenantName, &object.Object); err != nil {
 		return err
 	}
 
@@ -367,7 +368,7 @@ func (i *Index) putObject(ctx context.Context, object *storobj.Object,
 
 	i.backupStateLock.RLock()
 	defer i.backupStateLock.RUnlock()
-	shardName, err := i.determineObjectShard(object.ID(), tenantKey, nil)
+	shardName, err := i.determineObjectShard(object.ID(), object.Object.TenantName, nil)
 	if err != nil {
 		return err
 	}
@@ -515,7 +516,7 @@ func parseAsStringToTime(in interface{}) (time.Time, error) {
 // return value []error gives the error for the index with the positions
 // matching the inputs
 func (i *Index) putObjectBatch(ctx context.Context, objects []*storobj.Object,
-	replProps *additional.ReplicationProperties, tenantKey string,
+	replProps *additional.ReplicationProperties,
 ) []error {
 	i.backupStateLock.RLock()
 	defer i.backupStateLock.RUnlock()
@@ -524,12 +525,6 @@ func (i *Index) putObjectBatch(ctx context.Context, objects []*storobj.Object,
 		pos     []int
 	}
 	out := make([]error, len(objects))
-	if err := i.validateMultiTenancy(tenantKey, nil); err != nil {
-		for i := 0; i < len(out); i++ {
-			out[i] = err
-		}
-		return out
-	}
 
 	byShard := map[string]objsAndPos{}
 	className := string(i.Config.ClassName)
@@ -543,7 +538,7 @@ func (i *Index) putObjectBatch(ctx context.Context, objects []*storobj.Object,
 	}
 
 	for pos, obj := range objects {
-		shardName, err := i.determineObjectShard(obj.ID(), tenantKey, ss)
+		shardName, err := i.determineObjectShard(obj.ID(), obj.Object.TenantName, ss)
 		if err != nil {
 			out[pos] = err
 			continue
@@ -628,7 +623,7 @@ func (i *Index) IncomingBatchPutObjects(ctx context.Context, shardName string,
 
 // return value map[int]error gives the error for the index as it received it
 func (i *Index) addReferencesBatch(ctx context.Context, refs objects.BatchReferences,
-	replProps *additional.ReplicationProperties, tenantKey string,
+	replProps *additional.ReplicationProperties,
 ) []error {
 	i.backupStateLock.RLock()
 	defer i.backupStateLock.RUnlock()
@@ -637,10 +632,6 @@ func (i *Index) addReferencesBatch(ctx context.Context, refs objects.BatchRefere
 		pos  []int
 	}
 
-	if err := i.validateMultiTenancy(tenantKey, nil); err != nil {
-		return []error{err}
-	}
-
 	byShard := map[string]refsAndPos{}
 	out := make([]error, len(refs))
 	className := i.Config.ClassName.String()
@@ -654,7 +645,7 @@ func (i *Index) addReferencesBatch(ctx context.Context, refs objects.BatchRefere
 	}
 
 	for pos, ref := range refs {
-		shardName, err := i.determineObjectShard(ref.From.TargetID, tenantKey, ss)
+		shardName, err := i.determineObjectShard(ref.From.TargetID, ref.TenantName, ss)
 		if err != nil {
 			out[pos] = err
 			continue
@@ -1723,17 +1714,5 @@ func (i *Index) addNewShard(ctx context.Context,
 }
 
 func (i *Index) validateMultiTenancy(tenantKey string, object *models.Object) error {
-	if i.tenantKey != "" && tenantKey == "" {
-		return objects.NewErrInvalidUserInput("class %q has multi-tenancy enabled, tenant_key %q required",
-			i.Config.ClassName, i.tenantKey)
-	}
-	if object != nil {
-		parsedTenantKey := objects.ParseTenantKeyFromObject(i.tenantKey, object, i.logger)
-		if parsedTenantKey != tenantKey {
-			return objects.NewErrInvalidUserInput(
-				"tenant_key query param value %q conflicts with object body value %q for class %q tenant key %q",
-				tenantKey, parsedTenantKey, i.Config.ClassName, i.tenantKey)
-		}
-	}
 	return nil
 }
diff --git a/client/batch/batch_objects_create_parameters.go b/client/batch/batch_objects_create_parameters.go
index e7b07bc17c..83c646a394 100644
--- a/client/batch/batch_objects_create_parameters.go
+++ b/client/batch/batch_objects_create_parameters.go
@@ -81,12 +81,6 @@ type BatchObjectsCreateParams struct {
 	*/
 	ConsistencyLevel *string
 
-	/* TenantKey.
-
-	   Specifies the tenant in a request targeting a multi-tenant class
-	*/
-	TenantKey *string
-
 	timeout    time.Duration
 	Context    context.Context
 	HTTPClient *http.Client
@@ -162,17 +156,6 @@ func (o *BatchObjectsCreateParams) SetConsistencyLevel(consistencyLevel *string)
 	o.ConsistencyLevel = consistencyLevel
 }
 
-// WithTenantKey adds the tenantKey to the batch objects create params
-func (o *BatchObjectsCreateParams) WithTenantKey(tenantKey *string) *BatchObjectsCreateParams {
-	o.SetTenantKey(tenantKey)
-	return o
-}
-
-// SetTenantKey adds the tenantKey to the batch objects create params
-func (o *BatchObjectsCreateParams) SetTenantKey(tenantKey *string) {
-	o.TenantKey = tenantKey
-}
-
 // WriteToRequest writes these params to a swagger request
 func (o *BatchObjectsCreateParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
 
@@ -201,23 +184,6 @@ func (o *BatchObjectsCreateParams) WriteToRequest(r runtime.ClientRequest, reg s
 		}
 	}
 
-	if o.TenantKey != nil {
-
-		// query param tenant_key
-		var qrTenantKey string
-
-		if o.TenantKey != nil {
-			qrTenantKey = *o.TenantKey
-		}
-		qTenantKey := qrTenantKey
-		if qTenantKey != "" {
-
-			if err := r.SetQueryParam("tenant_key", qTenantKey); err != nil {
-				return err
-			}
-		}
-	}
-
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
diff --git a/client/batch/batch_references_create_parameters.go b/client/batch/batch_references_create_parameters.go
index c2de101c71..b075ee791c 100644
--- a/client/batch/batch_references_create_parameters.go
+++ b/client/batch/batch_references_create_parameters.go
@@ -86,12 +86,6 @@ type BatchReferencesCreateParams struct {
 	*/
 	ConsistencyLevel *string
 
-	/* TenantKey.
-
-	   Specifies the tenant in a request targeting a multi-tenant class
-	*/
-	TenantKey *string
-
 	timeout    time.Duration
 	Context    context.Context
 	HTTPClient *http.Client
@@ -167,17 +161,6 @@ func (o *BatchReferencesCreateParams) SetConsistencyLevel(consistencyLevel *stri
 	o.ConsistencyLevel = consistencyLevel
 }
 
-// WithTenantKey adds the tenantKey to the batch references create params
-func (o *BatchReferencesCreateParams) WithTenantKey(tenantKey *string) *BatchReferencesCreateParams {
-	o.SetTenantKey(tenantKey)
-	return o
-}
-
-// SetTenantKey adds the tenantKey to the batch references create params
-func (o *BatchReferencesCreateParams) SetTenantKey(tenantKey *string) {
-	o.TenantKey = tenantKey
-}
-
 // WriteToRequest writes these params to a swagger request
 func (o *BatchReferencesCreateParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
 
@@ -208,23 +191,6 @@ func (o *BatchReferencesCreateParams) WriteToRequest(r runtime.ClientRequest, re
 		}
 	}
 
-	if o.TenantKey != nil {
-
-		// query param tenant_key
-		var qrTenantKey string
-
-		if o.TenantKey != nil {
-			qrTenantKey = *o.TenantKey
-		}
-		qTenantKey := qrTenantKey
-		if qTenantKey != "" {
-
-			if err := r.SetQueryParam("tenant_key", qTenantKey); err != nil {
-				return err
-			}
-		}
-	}
-
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
diff --git a/client/objects/objects_class_patch_parameters.go b/client/objects/objects_class_patch_parameters.go
index f09f28de98..3cd1f732bb 100644
--- a/client/objects/objects_class_patch_parameters.go
+++ b/client/objects/objects_class_patch_parameters.go
@@ -100,12 +100,6 @@ type ObjectsClassPatchParams struct {
 	*/
 	ID strfmt.UUID
 
-	/* TenantKey.
-
-	   Specifies the tenant in a request targeting a multi-tenant class
-	*/
-	TenantKey *string
-
 	timeout    time.Duration
 	Context    context.Context
 	HTTPClient *http.Client
@@ -203,17 +197,6 @@ func (o *ObjectsClassPatchParams) SetID(id strfmt.UUID) {
 	o.ID = id
 }
 
-// WithTenantKey adds the tenantKey to the objects class patch params
-func (o *ObjectsClassPatchParams) WithTenantKey(tenantKey *string) *ObjectsClassPatchParams {
-	o.SetTenantKey(tenantKey)
-	return o
-}
-
-// SetTenantKey adds the tenantKey to the objects class patch params
-func (o *ObjectsClassPatchParams) SetTenantKey(tenantKey *string) {
-	o.TenantKey = tenantKey
-}
-
 // WriteToRequest writes these params to a swagger request
 func (o *ObjectsClassPatchParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
 
@@ -254,23 +237,6 @@ func (o *ObjectsClassPatchParams) WriteToRequest(r runtime.ClientRequest, reg st
 		return err
 	}
 
-	if o.TenantKey != nil {
-
-		// query param tenant_key
-		var qrTenantKey string
-
-		if o.TenantKey != nil {
-			qrTenantKey = *o.TenantKey
-		}
-		qTenantKey := qrTenantKey
-		if qTenantKey != "" {
-
-			if err := r.SetQueryParam("tenant_key", qTenantKey); err != nil {
-				return err
-			}
-		}
-	}
-
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
diff --git a/client/objects/objects_class_put_parameters.go b/client/objects/objects_class_put_parameters.go
index 9d2a80e802..4ef2ff06c0 100644
--- a/client/objects/objects_class_put_parameters.go
+++ b/client/objects/objects_class_put_parameters.go
@@ -94,12 +94,6 @@ type ObjectsClassPutParams struct {
 	*/
 	ID strfmt.UUID
 
-	/* TenantKey.
-
-	   Specifies the tenant in a request targeting a multi-tenant class
-	*/
-	TenantKey *string
-
 	timeout    time.Duration
 	Context    context.Context
 	HTTPClient *http.Client
@@ -197,17 +191,6 @@ func (o *ObjectsClassPutParams) SetID(id strfmt.UUID) {
 	o.ID = id
 }
 
-// WithTenantKey adds the tenantKey to the objects class put params
-func (o *ObjectsClassPutParams) WithTenantKey(tenantKey *string) *ObjectsClassPutParams {
-	o.SetTenantKey(tenantKey)
-	return o
-}
-
-// SetTenantKey adds the tenantKey to the objects class put params
-func (o *ObjectsClassPutParams) SetTenantKey(tenantKey *string) {
-	o.TenantKey = tenantKey
-}
-
 // WriteToRequest writes these params to a swagger request
 func (o *ObjectsClassPutParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
 
@@ -248,23 +231,6 @@ func (o *ObjectsClassPutParams) WriteToRequest(r runtime.ClientRequest, reg strf
 		return err
 	}
 
-	if o.TenantKey != nil {
-
-		// query param tenant_key
-		var qrTenantKey string
-
-		if o.TenantKey != nil {
-			qrTenantKey = *o.TenantKey
-		}
-		qTenantKey := qrTenantKey
-		if qTenantKey != "" {
-
-			if err := r.SetQueryParam("tenant_key", qTenantKey); err != nil {
-				return err
-			}
-		}
-	}
-
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
diff --git a/client/objects/objects_create_parameters.go b/client/objects/objects_create_parameters.go
index 74af67b439..ce5bb90a56 100644
--- a/client/objects/objects_create_parameters.go
+++ b/client/objects/objects_create_parameters.go
@@ -83,12 +83,6 @@ type ObjectsCreateParams struct {
 	*/
 	ConsistencyLevel *string
 
-	/* TenantKey.
-
-	   Specifies the tenant in a request targeting a multi-tenant class
-	*/
-	TenantKey *string
-
 	timeout    time.Duration
 	Context    context.Context
 	HTTPClient *http.Client
@@ -164,17 +158,6 @@ func (o *ObjectsCreateParams) SetConsistencyLevel(consistencyLevel *string) {
 	o.ConsistencyLevel = consistencyLevel
 }
 
-// WithTenantKey adds the tenantKey to the objects create params
-func (o *ObjectsCreateParams) WithTenantKey(tenantKey *string) *ObjectsCreateParams {
-	o.SetTenantKey(tenantKey)
-	return o
-}
-
-// SetTenantKey adds the tenantKey to the objects create params
-func (o *ObjectsCreateParams) SetTenantKey(tenantKey *string) {
-	o.TenantKey = tenantKey
-}
-
 // WriteToRequest writes these params to a swagger request
 func (o *ObjectsCreateParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
 
@@ -205,23 +188,6 @@ func (o *ObjectsCreateParams) WriteToRequest(r runtime.ClientRequest, reg strfmt
 		}
 	}
 
-	if o.TenantKey != nil {
-
-		// query param tenant_key
-		var qrTenantKey string
-
-		if o.TenantKey != nil {
-			qrTenantKey = *o.TenantKey
-		}
-		qTenantKey := qrTenantKey
-		if qTenantKey != "" {
-
-			if err := r.SetQueryParam("tenant_key", qTenantKey); err != nil {
-				return err
-			}
-		}
-	}
-
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
diff --git a/client/objects/objects_patch_parameters.go b/client/objects/objects_patch_parameters.go
index e4c0fcac51..15ae4bbfca 100644
--- a/client/objects/objects_patch_parameters.go
+++ b/client/objects/objects_patch_parameters.go
@@ -94,12 +94,6 @@ type ObjectsPatchParams struct {
 	*/
 	ID strfmt.UUID
 
-	/* TenantKey.
-
-	   Specifies the tenant in a request targeting a multi-tenant class
-	*/
-	TenantKey *string
-
 	timeout    time.Duration
 	Context    context.Context
 	HTTPClient *http.Client
@@ -186,17 +180,6 @@ func (o *ObjectsPatchParams) SetID(id strfmt.UUID) {
 	o.ID = id
 }
 
-// WithTenantKey adds the tenantKey to the objects patch params
-func (o *ObjectsPatchParams) WithTenantKey(tenantKey *string) *ObjectsPatchParams {
-	o.SetTenantKey(tenantKey)
-	return o
-}
-
-// SetTenantKey adds the tenantKey to the objects patch params
-func (o *ObjectsPatchParams) SetTenantKey(tenantKey *string) {
-	o.TenantKey = tenantKey
-}
-
 // WriteToRequest writes these params to a swagger request
 func (o *ObjectsPatchParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
 
@@ -232,23 +215,6 @@ func (o *ObjectsPatchParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.
 		return err
 	}
 
-	if o.TenantKey != nil {
-
-		// query param tenant_key
-		var qrTenantKey string
-
-		if o.TenantKey != nil {
-			qrTenantKey = *o.TenantKey
-		}
-		qTenantKey := qrTenantKey
-		if qTenantKey != "" {
-
-			if err := r.SetQueryParam("tenant_key", qTenantKey); err != nil {
-				return err
-			}
-		}
-	}
-
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
diff --git a/client/objects/objects_update_parameters.go b/client/objects/objects_update_parameters.go
index 694719765f..cba965c4b8 100644
--- a/client/objects/objects_update_parameters.go
+++ b/client/objects/objects_update_parameters.go
@@ -91,12 +91,6 @@ type ObjectsUpdateParams struct {
 	*/
 	ID strfmt.UUID
 
-	/* TenantKey.
-
-	   Specifies the tenant in a request targeting a multi-tenant class
-	*/
-	TenantKey *string
-
 	timeout    time.Duration
 	Context    context.Context
 	HTTPClient *http.Client
@@ -183,17 +177,6 @@ func (o *ObjectsUpdateParams) SetID(id strfmt.UUID) {
 	o.ID = id
 }
 
-// WithTenantKey adds the tenantKey to the objects update params
-func (o *ObjectsUpdateParams) WithTenantKey(tenantKey *string) *ObjectsUpdateParams {
-	o.SetTenantKey(tenantKey)
-	return o
-}
-
-// SetTenantKey adds the tenantKey to the objects update params
-func (o *ObjectsUpdateParams) SetTenantKey(tenantKey *string) {
-	o.TenantKey = tenantKey
-}
-
 // WriteToRequest writes these params to a swagger request
 func (o *ObjectsUpdateParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
 
@@ -229,23 +212,6 @@ func (o *ObjectsUpdateParams) WriteToRequest(r runtime.ClientRequest, reg strfmt
 		return err
 	}
 
-	if o.TenantKey != nil {
-
-		// query param tenant_key
-		var qrTenantKey string
-
-		if o.TenantKey != nil {
-			qrTenantKey = *o.TenantKey
-		}
-		qTenantKey := qrTenantKey
-		if qTenantKey != "" {
-
-			if err := r.SetQueryParam("tenant_key", qTenantKey); err != nil {
-				return err
-			}
-		}
-	}
-
 	if len(res) > 0 {
 		return errors.CompositeValidationError(res...)
 	}
diff --git a/entities/models/batch_reference.go b/entities/models/batch_reference.go
index f44c35347f..cfa4edf571 100644
--- a/entities/models/batch_reference.go
+++ b/entities/models/batch_reference.go
@@ -35,6 +35,9 @@ type BatchReference struct {
 	// Format: uri
 	From strfmt.URI `json:"from,omitempty"`
 
+	// Name of the reference tenant.
+	TenantName string `json:"tenantName,omitempty"`
+
 	// Short-form URI to point to the cross-ref. Should be in the form of weaviate://localhost/<uuid> for the example of a local cross-ref to an object
 	// Example: weaviate://localhost/97525810-a9a5-4eb0-858a-71449aeb007f
 	// Format: uri
diff --git a/entities/models/multi_tenancy_config.go b/entities/models/multi_tenancy_config.go
index b5d917d611..e0ee23e802 100644
--- a/entities/models/multi_tenancy_config.go
+++ b/entities/models/multi_tenancy_config.go
@@ -30,9 +30,6 @@ type MultiTenancyConfig struct {
 
 	// Whether or not multi-tenancy is enabled for this class
 	Enabled bool `json:"enabled,omitempty"`
-
-	// The class property which is used to separate tenants
-	TenantKey string `json:"tenantKey,omitempty"`
 }
 
 // Validate validates this multi tenancy config
diff --git a/entities/models/object.go b/entities/models/object.go
index 388b7d7696..8390937944 100644
--- a/entities/models/object.go
+++ b/entities/models/object.go
@@ -49,6 +49,9 @@ type Object struct {
 	// properties
 	Properties PropertySchema `json:"properties,omitempty"`
 
+	// Name of the Objects tenant.
+	TenantName string `json:"tenantName,omitempty"`
+
 	// This object's position in the Contextionary vector space. Read-only if using a vectorizer other than 'none'. Writable and required if using 'none' as vectorizer.
 	Vector C11yVector `json:"vector,omitempty"`
 
diff --git a/openapi-specs/schema.json b/openapi-specs/schema.json
index 70ff3a1ad8..192efd15fe 100644
--- a/openapi-specs/schema.json
+++ b/openapi-specs/schema.json
@@ -417,10 +417,6 @@
         "enabled": {
           "description": "Whether or not multi-tenancy is enabled for this class",
           "type": "boolean"
-        },
-        "tenantKey": {
-          "description": "The class property which is used to separate tenants",
-          "type": "string"
         }
       }
     },
@@ -1138,6 +1134,10 @@
           "example": "weaviate://localhost/97525810-a9a5-4eb0-858a-71449aeb007f",
           "format": "uri",
           "type": "string"
+        },
+        "tenantName" : {
+          "type": "string",
+          "description": "Name of the reference tenant."
         }
       }
     },
@@ -1252,6 +1252,10 @@
           "description": "This object's position in the Contextionary vector space. Read-only if using a vectorizer other than 'none'. Writable and required if using 'none' as vectorizer.",
           "$ref": "#/definitions/C11yVector"
         },
+        "tenantName": {
+          "description": "Name of the Objects tenant.",
+          "type": "string"
+        },
         "additional": {
           "$ref": "#/definitions/AdditionalProperties"
         }
@@ -1954,9 +1958,6 @@
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -2141,9 +2142,6 @@
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -2211,9 +2209,6 @@
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -2473,9 +2468,6 @@
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -2550,9 +2542,6 @@
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -3206,9 +3195,6 @@
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
@@ -3345,9 +3331,6 @@
           },
           {
             "$ref": "#/parameters/CommonConsistencyLevelParameterQuery"
-          },
-          {
-            "$ref": "#/parameters/CommonTenantKeyParameterQuery"
           }
         ],
         "responses": {
diff --git a/usecases/classification/classifier.go b/usecases/classification/classifier.go
index 206dd04ab0..eefb92ef36 100644
--- a/usecases/classification/classifier.go
+++ b/usecases/classification/classifier.go
@@ -112,7 +112,7 @@ type VectorRepo interface {
 type vectorRepo interface {
 	VectorRepo
 	BatchPutObjects(ctx context.Context, objects objects.BatchObjects,
-		repl *additional.ReplicationProperties, tenantKey string) (objects.BatchObjects, error)
+		repl *additional.ReplicationProperties) (objects.BatchObjects, error)
 }
 
 // NeighborRef is the result of an aggregation of the ref properties of k
diff --git a/usecases/classification/writer.go b/usecases/classification/writer.go
index 12a78a250f..3cfcdff76c 100644
--- a/usecases/classification/writer.go
+++ b/usecases/classification/writer.go
@@ -123,7 +123,7 @@ func (r *batchWriter) saveObjects(items objects.BatchObjects) {
 	defer cancel()
 
 	if len(items) > 0 {
-		saved, err := r.vectorRepo.BatchPutObjects(ctx, items, nil, "")
+		saved, err := r.vectorRepo.BatchPutObjects(ctx, items, nil)
 		if err != nil {
 			r.ec.Add(err)
 		}
diff --git a/usecases/objects/add.go b/usecases/objects/add.go
index cfc9bea4c8..60cdf03d4e 100644
--- a/usecases/objects/add.go
+++ b/usecases/objects/add.go
@@ -37,7 +37,7 @@ type schemaManager interface {
 
 // AddObject Class Instance to the connected DB.
 func (m *Manager) AddObject(ctx context.Context, principal *models.Principal, object *models.Object,
-	repl *additional.ReplicationProperties, tenantKey string,
+	repl *additional.ReplicationProperties,
 ) (*models.Object, error) {
 	err := m.authorizer.Authorize(principal, "create", "objects")
 	if err != nil {
@@ -53,7 +53,7 @@ func (m *Manager) AddObject(ctx context.Context, principal *models.Principal, ob
 	m.metrics.AddObjectInc()
 	defer m.metrics.AddObjectDec()
 
-	return m.addObjectToConnectorAndSchema(ctx, principal, object, repl, tenantKey)
+	return m.addObjectToConnectorAndSchema(ctx, principal, object, repl)
 }
 
 func (m *Manager) checkIDOrAssignNew(ctx context.Context, class string, id strfmt.UUID,
@@ -84,9 +84,9 @@ func (m *Manager) checkIDOrAssignNew(ctx context.Context, class string, id strfm
 }
 
 func (m *Manager) addObjectToConnectorAndSchema(ctx context.Context, principal *models.Principal,
-	object *models.Object, repl *additional.ReplicationProperties, tenantKey string,
+	object *models.Object, repl *additional.ReplicationProperties,
 ) (*models.Object, error) {
-	id, err := m.checkIDOrAssignNew(ctx, object.Class, object.ID, repl, tenantKey)
+	id, err := m.checkIDOrAssignNew(ctx, object.Class, object.ID, repl, object.TenantName)
 	if err != nil {
 		return nil, err
 	}
@@ -97,7 +97,7 @@ func (m *Manager) addObjectToConnectorAndSchema(ctx context.Context, principal *
 		return nil, NewErrInvalidUserInput("invalid object: %v", err)
 	}
 
-	err = m.validateObjectAndNormalizeNames(ctx, principal, repl, object, nil, tenantKey)
+	err = m.validateObjectAndNormalizeNames(ctx, principal, repl, object, nil)
 	if err != nil {
 		return nil, NewErrInvalidUserInput("invalid object: %v", err)
 	}
@@ -117,7 +117,7 @@ func (m *Manager) addObjectToConnectorAndSchema(ctx context.Context, principal *
 		return nil, err
 	}
 
-	err = m.vectorRepo.PutObject(ctx, object, object.Vector, repl, tenantKey)
+	err = m.vectorRepo.PutObject(ctx, object, object.Vector, repl)
 	if err != nil {
 		return nil, fmt.Errorf("put object: %w", err)
 	}
@@ -127,14 +127,14 @@ func (m *Manager) addObjectToConnectorAndSchema(ctx context.Context, principal *
 
 func (m *Manager) validateObjectAndNormalizeNames(ctx context.Context,
 	principal *models.Principal, repl *additional.ReplicationProperties,
-	incoming *models.Object, existing *models.Object, tenantKey string,
+	incoming *models.Object, existing *models.Object,
 ) error {
 	class, err := m.validateSchema(ctx, principal, incoming)
 	if err != nil {
 		return err
 	}
 
-	return validation.New(m.vectorRepo.Exists, m.config, repl, tenantKey).
+	return validation.New(m.vectorRepo.Exists, m.config, repl).
 		Object(ctx, class, incoming, existing)
 }
 
diff --git a/usecases/objects/batch_add.go b/usecases/objects/batch_add.go
index bfa7c8b664..8aea33a640 100644
--- a/usecases/objects/batch_add.go
+++ b/usecases/objects/batch_add.go
@@ -29,7 +29,6 @@ import (
 // AddObjects Class Instances in batch to the connected DB
 func (b *BatchManager) AddObjects(ctx context.Context, principal *models.Principal,
 	objects []*models.Object, fields []*string, repl *additional.ReplicationProperties,
-	tenantKey string,
 ) (BatchObjects, error) {
 	err := b.authorizer.Authorize(principal, "create", "batch/objects")
 	if err != nil {
@@ -47,19 +46,18 @@ func (b *BatchManager) AddObjects(ctx context.Context, principal *models.Princip
 	defer b.metrics.BatchOp("total_uc_level", before.UnixNano())
 	defer b.metrics.BatchDec()
 
-	return b.addObjects(ctx, principal, objects, fields, repl, tenantKey)
+	return b.addObjects(ctx, principal, objects, fields, repl)
 }
 
 func (b *BatchManager) addObjects(ctx context.Context, principal *models.Principal,
 	classes []*models.Object, fields []*string, repl *additional.ReplicationProperties,
-	tenantKey string,
 ) (BatchObjects, error) {
 	beforePreProcessing := time.Now()
 	if err := b.validateObjectForm(classes); err != nil {
 		return nil, NewErrInvalidUserInput("invalid param 'objects': %v", err)
 	}
 
-	batchObjects := b.validateObjectsConcurrently(ctx, principal, classes, fields, repl, tenantKey)
+	batchObjects := b.validateObjectsConcurrently(ctx, principal, classes, fields, repl)
 	b.metrics.BatchOp("total_preprocessing", beforePreProcessing.UnixNano())
 
 	var (
@@ -69,7 +67,7 @@ func (b *BatchManager) addObjects(ctx context.Context, principal *models.Princip
 
 	beforePersistence := time.Now()
 	defer b.metrics.BatchOp("total_persistence_level", beforePersistence.UnixNano())
-	if res, err = b.vectorRepo.BatchPutObjects(ctx, batchObjects, repl, tenantKey); err != nil {
+	if res, err = b.vectorRepo.BatchPutObjects(ctx, batchObjects, repl); err != nil {
 		return nil, NewErrInternal("batch objects: %#v", err)
 	}
 
@@ -86,7 +84,6 @@ func (b *BatchManager) validateObjectForm(classes []*models.Object) error {
 
 func (b *BatchManager) validateObjectsConcurrently(ctx context.Context, principal *models.Principal,
 	objects []*models.Object, fields []*string, repl *additional.ReplicationProperties,
-	tenantKey string,
 ) BatchObjects {
 	fieldsToKeep := determineResponseFields(fields)
 	c := make(chan BatchObject, len(objects))
@@ -105,7 +102,7 @@ func (b *BatchManager) validateObjectsConcurrently(ctx context.Context, principa
 		i := i
 		object := object
 		eg.Go(func() error {
-			b.validateObject(ctx, principal, object, i, &c, fieldsToKeep, repl, tenantKey)
+			b.validateObject(ctx, principal, object, i, &c, fieldsToKeep, repl)
 			return nil
 		})
 	}
@@ -118,7 +115,6 @@ func (b *BatchManager) validateObjectsConcurrently(ctx context.Context, principa
 func (b *BatchManager) validateObject(ctx context.Context, principal *models.Principal,
 	concept *models.Object, originalIndex int, resultsC *chan BatchObject,
 	fieldsToKeep map[string]struct{}, repl *additional.ReplicationProperties,
-	tenantKey string,
 ) {
 	var id strfmt.UUID
 
@@ -144,6 +140,7 @@ func (b *BatchManager) validateObject(ctx context.Context, principal *models.Pri
 	object.LastUpdateTimeUnix = 0
 	object.ID = id
 	object.Vector = concept.Vector
+	object.TenantName = concept.TenantName
 
 	if _, ok := fieldsToKeep["class"]; ok {
 		object.Class = concept.Class
@@ -167,10 +164,7 @@ func (b *BatchManager) validateObject(ctx context.Context, principal *models.Pri
 	if class == nil {
 		ec.Add(fmt.Errorf("class '%s' not present in schema", object.Class))
 	} else {
-		err = validateSingleBatchObjectTenantKey(class, concept, tenantKey, ec, b.logger)
-		ec.Add(err)
-
-		err = validation.New(b.vectorRepo.Exists, b.config, repl, tenantKey).
+		err = validation.New(b.vectorRepo.Exists, b.config, repl).
 			Object(ctx, class, object, nil)
 		ec.Add(err)
 
diff --git a/usecases/objects/batch_manager.go b/usecases/objects/batch_manager.go
index 01c31f6da8..db463d7427 100644
--- a/usecases/objects/batch_manager.go
+++ b/usecases/objects/batch_manager.go
@@ -41,11 +41,11 @@ type BatchVectorRepo interface {
 
 type batchRepoNew interface {
 	BatchPutObjects(ctx context.Context, objects BatchObjects,
-		repl *additional.ReplicationProperties, tenantKey string) (BatchObjects, error)
+		repl *additional.ReplicationProperties) (BatchObjects, error)
 	BatchDeleteObjects(ctx context.Context, params BatchDeleteParams,
 		repl *additional.ReplicationProperties, tenantKey string) (BatchDeleteResult, error)
 	AddBatchReferences(ctx context.Context, references BatchReferences,
-		repl *additional.ReplicationProperties, tenantKey string) (BatchReferences, error)
+		repl *additional.ReplicationProperties) (BatchReferences, error)
 }
 
 // NewBatchManager creates a new manager
diff --git a/usecases/objects/batch_references_add.go b/usecases/objects/batch_references_add.go
index 7561c27e59..ff3874e2f2 100644
--- a/usecases/objects/batch_references_add.go
+++ b/usecases/objects/batch_references_add.go
@@ -24,7 +24,7 @@ import (
 
 // AddReferences Class Instances in batch to the connected DB
 func (b *BatchManager) AddReferences(ctx context.Context, principal *models.Principal,
-	refs []*models.BatchReference, repl *additional.ReplicationProperties, tenantKey string,
+	refs []*models.BatchReference, repl *additional.ReplicationProperties,
 ) (BatchReferences, error) {
 	err := b.authorizer.Authorize(principal, "update", "batch/*")
 	if err != nil {
@@ -40,19 +40,18 @@ func (b *BatchManager) AddReferences(ctx context.Context, principal *models.Prin
 	b.metrics.BatchRefInc()
 	defer b.metrics.BatchRefDec()
 
-	return b.addReferences(ctx, principal, refs, repl, tenantKey)
+	return b.addReferences(ctx, principal, refs, repl)
 }
 
 func (b *BatchManager) addReferences(ctx context.Context, principal *models.Principal,
 	refs []*models.BatchReference, repl *additional.ReplicationProperties,
-	tenantKey string,
 ) (BatchReferences, error) {
 	if err := b.validateReferenceForm(refs); err != nil {
 		return nil, NewErrInvalidUserInput("invalid params: %v", err)
 	}
 
-	batchReferences := b.validateReferencesConcurrently(ctx, principal, refs, tenantKey)
-	if res, err := b.vectorRepo.AddBatchReferences(ctx, batchReferences, repl, tenantKey); err != nil {
+	batchReferences := b.validateReferencesConcurrently(ctx, principal, refs)
+	if res, err := b.vectorRepo.AddBatchReferences(ctx, batchReferences, repl); err != nil {
 		return nil, NewErrInternal("could not add batch request to connector: %v", err)
 	} else {
 		return res, nil
@@ -68,7 +67,7 @@ func (b *BatchManager) validateReferenceForm(refs []*models.BatchReference) erro
 }
 
 func (b *BatchManager) validateReferencesConcurrently(ctx context.Context,
-	principal *models.Principal, refs []*models.BatchReference, tenantKey string,
+	principal *models.Principal, refs []*models.BatchReference,
 ) BatchReferences {
 	c := make(chan BatchReference, len(refs))
 	wg := new(sync.WaitGroup)
@@ -76,7 +75,7 @@ func (b *BatchManager) validateReferencesConcurrently(ctx context.Context,
 	// Generate a goroutine for each separate request
 	for i, ref := range refs {
 		wg.Add(1)
-		go b.validateReference(ctx, principal, wg, ref, i, &c, tenantKey)
+		go b.validateReference(ctx, principal, wg, ref, i, &c)
 	}
 
 	wg.Wait()
@@ -86,7 +85,6 @@ func (b *BatchManager) validateReferencesConcurrently(ctx context.Context,
 
 func (b *BatchManager) validateReference(ctx context.Context, principal *models.Principal,
 	wg *sync.WaitGroup, ref *models.BatchReference, i int, resultsC *chan BatchReference,
-	tenantKey string,
 ) {
 	defer wg.Done()
 	var errors []error
@@ -113,10 +111,10 @@ func (b *BatchManager) validateReference(ctx context.Context, principal *models.
 		err = joinErrors(errors)
 	}
 
-	if err == nil && shouldValidateMultiTenantRef(tenantKey, source, target) {
+	if err == nil && shouldValidateMultiTenantRef(ref.TenantName, source, target) {
 		// can only validate multi-tenancy when everything above succeeds
 		err = validateReferenceMultiTenancy(ctx, principal,
-			b.schemaManager, b.vectorRepo, source, target, tenantKey)
+			b.schemaManager, b.vectorRepo, source, target, ref.TenantName)
 	}
 
 	*resultsC <- BatchReference{
@@ -124,6 +122,7 @@ func (b *BatchManager) validateReference(ctx context.Context, principal *models.
 		To:            target,
 		Err:           err,
 		OriginalIndex: i,
+		TenantName:    ref.TenantName,
 	}
 }
 
diff --git a/usecases/objects/batch_types.go b/usecases/objects/batch_types.go
index 28d99e6a0c..c9038c1b59 100644
--- a/usecases/objects/batch_types.go
+++ b/usecases/objects/batch_types.go
@@ -55,6 +55,7 @@ type BatchReference struct {
 	Err           error               `json:"err"`
 	From          *crossref.RefSource `json:"from"`
 	To            *crossref.Ref       `json:"to"`
+	TenantName    string              `json:"tenantName"`
 }
 
 // BatchReferences groups many Reference items together. The order matches the
diff --git a/usecases/objects/manager.go b/usecases/objects/manager.go
index 794e38c69e..865d516584 100644
--- a/usecases/objects/manager.go
+++ b/usecases/objects/manager.go
@@ -91,7 +91,7 @@ type authorizer interface {
 
 type VectorRepo interface {
 	PutObject(ctx context.Context, concept *models.Object, vector []float32,
-		repl *additional.ReplicationProperties, tenantKey string) error
+		repl *additional.ReplicationProperties) error
 	DeleteObject(ctx context.Context, className string, id strfmt.UUID,
 		repl *additional.ReplicationProperties, tenantKey string) error
 	// Object returns object of the specified class giving by its id
diff --git a/usecases/objects/merge.go b/usecases/objects/merge.go
index d9319112c9..ab4194ac43 100644
--- a/usecases/objects/merge.go
+++ b/usecases/objects/merge.go
@@ -37,7 +37,7 @@ type MergeDocument struct {
 }
 
 func (m *Manager) MergeObject(ctx context.Context, principal *models.Principal,
-	updates *models.Object, repl *additional.ReplicationProperties, tenantKey string,
+	updates *models.Object, repl *additional.ReplicationProperties,
 ) *Error {
 	if err := m.validateInputs(updates); err != nil {
 		return &Error{"bad request", StatusBadRequest, err}
@@ -51,7 +51,7 @@ func (m *Manager) MergeObject(ctx context.Context, principal *models.Principal,
 	m.metrics.MergeObjectInc()
 	defer m.metrics.MergeObjectDec()
 
-	obj, err := m.vectorRepo.Object(ctx, cls, id, nil, additional.Properties{}, repl, tenantKey)
+	obj, err := m.vectorRepo.Object(ctx, cls, id, nil, additional.Properties{}, repl, updates.TenantName)
 	if err != nil {
 		return &Error{"repo.object", StatusInternalServerError, err}
 	}
@@ -69,7 +69,7 @@ func (m *Manager) MergeObject(ctx context.Context, principal *models.Principal,
 	}
 
 	if err := m.validateObjectAndNormalizeNames(
-		ctx, principal, repl, updates, obj.Object(), tenantKey); err != nil {
+		ctx, principal, repl, updates, obj.Object()); err != nil {
 		return &Error{"bad request", StatusBadRequest, err}
 	}
 
@@ -77,7 +77,7 @@ func (m *Manager) MergeObject(ctx context.Context, principal *models.Principal,
 		updates.Properties = map[string]interface{}{}
 	}
 
-	return m.patchObject(ctx, principal, obj, updates, repl, propertiesToDelete, tenantKey)
+	return m.patchObject(ctx, principal, obj, updates, repl, propertiesToDelete, updates.TenantName)
 }
 
 // patchObject patches an existing object obj with updates
diff --git a/usecases/objects/multi_tenancy.go b/usecases/objects/multi_tenancy.go
deleted file mode 100644
index 0da87423eb..0000000000
--- a/usecases/objects/multi_tenancy.go
+++ /dev/null
@@ -1,56 +0,0 @@
-//                           _       _
-// __      _____  __ ___   ___  __ _| |_ ___
-// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
-//  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
-//   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
-//
-//  Copyright © 2016 - 2023 Weaviate B.V. All rights reserved.
-//
-//  CONTACT: hello@weaviate.io
-//
-
-package objects
-
-import (
-	"fmt"
-
-	"github.com/google/uuid"
-	"github.com/sirupsen/logrus"
-	"github.com/weaviate/weaviate/entities/errorcompounder"
-	"github.com/weaviate/weaviate/entities/models"
-)
-
-// ParseTenantKeyFromObject extract the value of the tenant key if it exists
-func ParseTenantKeyFromObject(tenantKeyName string, o *models.Object, logger logrus.FieldLogger) string {
-	if props, _ := o.Properties.(map[string]interface{}); props != nil {
-		if rawVal := props[tenantKeyName]; rawVal != nil {
-			switch typed := rawVal.(type) {
-			case string:
-				return typed
-			case uuid.UUID:
-				return typed.String()
-			default:
-				logger.WithField("action", "parse_object_tenant_key").
-					Warnf("unsupported tenant key %+v of type %T", rawVal, rawVal)
-			}
-		}
-	}
-	return ""
-}
-
-func validateSingleBatchObjectTenantKey(class *models.Class, obj *models.Object,
-	tk string, ec *errorcompounder.ErrorCompounder, logger logrus.FieldLogger,
-) error {
-	var objTk string
-	if class.MultiTenancyConfig != nil {
-		if tk == "" {
-			return NewErrInvalidUserInput("class %q has multi-tenancy enabled, tenant_key %q required",
-				class.Class, class.MultiTenancyConfig.TenantKey)
-		}
-		objTk = ParseTenantKeyFromObject(class.MultiTenancyConfig.TenantKey, obj, logger)
-		if objTk != tk {
-			ec.Add(fmt.Errorf("object does not belong to tenant %q", tk))
-		}
-	}
-	return nil
-}
diff --git a/usecases/objects/references_add.go b/usecases/objects/references_add.go
index f43da6a5a2..8702d8c9b0 100644
--- a/usecases/objects/references_add.go
+++ b/usecases/objects/references_add.go
@@ -57,8 +57,8 @@ func (m *Manager) AddObjectReference(ctx context.Context, principal *models.Prin
 	}
 	defer unlock()
 
-	validator := validation.New(m.vectorRepo.Exists, m.config, repl, tenantKey)
-	if err := input.validate(ctx, principal, validator, m.schemaManager); err != nil {
+	validator := validation.New(m.vectorRepo.Exists, m.config, repl)
+	if err := input.validate(ctx, principal, validator, m.schemaManager, tenantKey); err != nil {
 		return &Error{"validate inputs", StatusBadRequest, err}
 	}
 	if !deprecatedEndpoint {
@@ -118,12 +118,12 @@ func (req *AddReferenceInput) validate(
 	ctx context.Context,
 	principal *models.Principal,
 	v *validation.Validator,
-	sm schemaManager,
+	sm schemaManager, tenant string,
 ) error {
 	if err := validateReferenceName(req.Class, req.Property); err != nil {
 		return err
 	}
-	if err := v.ValidateSingleRef(ctx, &req.Ref, "validate reference"); err != nil {
+	if err := v.ValidateSingleRef(ctx, &req.Ref, "validate reference", tenant); err != nil {
 		return err
 	}
 
diff --git a/usecases/objects/references_delete.go b/usecases/objects/references_delete.go
index 666791dd83..0ef3a7f062 100644
--- a/usecases/objects/references_delete.go
+++ b/usecases/objects/references_delete.go
@@ -34,14 +34,14 @@ type DeleteReferenceInput struct {
 }
 
 func (m *Manager) DeleteObjectReference(ctx context.Context, principal *models.Principal,
-	input *DeleteReferenceInput, repl *additional.ReplicationProperties, tenantKey string,
+	input *DeleteReferenceInput, repl *additional.ReplicationProperties, tenant string,
 ) *Error {
 	m.metrics.DeleteReferenceInc()
 	defer m.metrics.DeleteReferenceDec()
 
 	deprecatedEndpoint := input.Class == ""
 	res, err := m.getObjectFromRepo(ctx, input.Class, input.ID,
-		additional.Properties{}, nil, tenantKey)
+		additional.Properties{}, nil, tenant)
 	if err != nil {
 		errnf := ErrNotFound{}
 		if errors.As(err, &errnf) {
@@ -70,6 +70,7 @@ func (m *Manager) DeleteObjectReference(ctx context.Context, principal *models.P
 	}
 
 	obj := res.Object()
+	obj.TenantName = tenant
 	ok, errmsg := removeReference(obj, input.Property, &input.Reference)
 	if errmsg != "" {
 		return &Error{errmsg, StatusInternalServerError, nil}
@@ -79,7 +80,7 @@ func (m *Manager) DeleteObjectReference(ctx context.Context, principal *models.P
 	}
 	obj.LastUpdateTimeUnix = m.timeSource.Now()
 
-	err = m.vectorRepo.PutObject(ctx, obj, res.Vector, repl, tenantKey)
+	err = m.vectorRepo.PutObject(ctx, obj, res.Vector, repl)
 	if err != nil {
 		return &Error{"repo.putobject", StatusInternalServerError, err}
 	}
diff --git a/usecases/objects/references_update.go b/usecases/objects/references_update.go
index 731c71524d..511dac59a1 100644
--- a/usecases/objects/references_update.go
+++ b/usecases/objects/references_update.go
@@ -69,8 +69,8 @@ func (m *Manager) UpdateObjectReferences(ctx context.Context, principal *models.
 	}
 	defer unlock()
 
-	validator := validation.New(m.vectorRepo.Exists, m.config, repl, tenantKey)
-	if err := input.validate(ctx, principal, validator, m.schemaManager); err != nil {
+	validator := validation.New(m.vectorRepo.Exists, m.config, repl)
+	if err := input.validate(ctx, principal, validator, m.schemaManager, tenantKey); err != nil {
 		return &Error{"bad inputs", StatusBadRequest, err}
 	}
 	obj := res.Object()
@@ -80,7 +80,7 @@ func (m *Manager) UpdateObjectReferences(ctx context.Context, principal *models.
 		obj.Properties.(map[string]interface{})[input.Property] = input.Refs
 	}
 	obj.LastUpdateTimeUnix = m.timeSource.Now()
-	err = m.vectorRepo.PutObject(ctx, obj, res.Vector, repl, tenantKey)
+	err = m.vectorRepo.PutObject(ctx, obj, res.Vector, repl)
 	if err != nil {
 		return &Error{"repo.putobject", StatusInternalServerError, err}
 	}
@@ -91,12 +91,12 @@ func (req *PutReferenceInput) validate(
 	ctx context.Context,
 	principal *models.Principal,
 	v *validation.Validator,
-	sm schemaManager,
+	sm schemaManager, tenant string,
 ) error {
 	if err := validateReferenceName(req.Class, req.Property); err != nil {
 		return err
 	}
-	if err := v.ValidateMultipleRef(ctx, req.Refs, "validate references"); err != nil {
+	if err := v.ValidateMultipleRef(ctx, req.Refs, "validate references", tenant); err != nil {
 		return err
 	}
 
diff --git a/usecases/objects/update.go b/usecases/objects/update.go
index 1c9dfc7179..1bd633a441 100644
--- a/usecases/objects/update.go
+++ b/usecases/objects/update.go
@@ -25,7 +25,7 @@ import (
 // include this particular network ref class.
 func (m *Manager) UpdateObject(ctx context.Context, principal *models.Principal,
 	class string, id strfmt.UUID, updates *models.Object,
-	repl *additional.ReplicationProperties, tenantKey string,
+	repl *additional.ReplicationProperties,
 ) (*models.Object, error) {
 	path := fmt.Sprintf("objects/%s/%s", class, id)
 	if class == "" {
@@ -45,18 +45,18 @@ func (m *Manager) UpdateObject(ctx context.Context, principal *models.Principal,
 	}
 	defer unlock()
 
-	return m.updateObjectToConnectorAndSchema(ctx, principal, class, id, updates, repl, tenantKey)
+	return m.updateObjectToConnectorAndSchema(ctx, principal, class, id, updates, repl)
 }
 
 func (m *Manager) updateObjectToConnectorAndSchema(ctx context.Context,
 	principal *models.Principal, className string, id strfmt.UUID, updates *models.Object,
-	repl *additional.ReplicationProperties, tenantKey string,
+	repl *additional.ReplicationProperties,
 ) (*models.Object, error) {
 	if id != updates.ID {
 		return nil, NewErrInvalidUserInput("invalid update: field 'id' is immutable")
 	}
 
-	obj, err := m.getObjectFromRepo(ctx, className, id, additional.Properties{}, repl, tenantKey)
+	obj, err := m.getObjectFromRepo(ctx, className, id, additional.Properties{}, repl, updates.TenantName)
 	if err != nil {
 		return nil, err
 	}
@@ -69,7 +69,7 @@ func (m *Manager) updateObjectToConnectorAndSchema(ctx context.Context,
 		Debug("received update kind request")
 
 	err = m.validateObjectAndNormalizeNames(
-		ctx, principal, repl, updates, obj.Object(), tenantKey)
+		ctx, principal, repl, updates, obj.Object())
 	if err != nil {
 		return nil, NewErrInvalidUserInput("invalid object: %v", err)
 	}
@@ -90,7 +90,7 @@ func (m *Manager) updateObjectToConnectorAndSchema(ctx context.Context,
 		return nil, NewErrInternal("update object: %v", err)
 	}
 
-	err = m.vectorRepo.PutObject(ctx, updates, updates.Vector, repl, tenantKey)
+	err = m.vectorRepo.PutObject(ctx, updates, updates.Vector, repl)
 	if err != nil {
 		return nil, fmt.Errorf("put object: %w", err)
 	}
diff --git a/usecases/objects/validate.go b/usecases/objects/validate.go
index facd314095..05a72c9c8b 100644
--- a/usecases/objects/validate.go
+++ b/usecases/objects/validate.go
@@ -34,7 +34,7 @@ func (m *Manager) ValidateObject(ctx context.Context, principal *models.Principa
 	}
 	defer unlock()
 
-	err = m.validateObjectAndNormalizeNames(ctx, principal, repl, obj, nil, "")
+	err = m.validateObjectAndNormalizeNames(ctx, principal, repl, obj, nil)
 	if err != nil {
 		return NewErrInvalidUserInput("invalid object: %v", err)
 	}
diff --git a/usecases/objects/validation/model_validation.go b/usecases/objects/validation/model_validation.go
index b9cbdad6ba..ee2182f5fa 100644
--- a/usecases/objects/validation/model_validation.go
+++ b/usecases/objects/validation/model_validation.go
@@ -65,17 +65,15 @@ type Validator struct {
 	exists           exists
 	config           *config.WeaviateConfig
 	replicationProps *additional.ReplicationProperties
-	tenantKey        string
 }
 
 func New(exists exists, config *config.WeaviateConfig,
-	repl *additional.ReplicationProperties, tenantKey string,
+	repl *additional.ReplicationProperties,
 ) *Validator {
 	return &Validator{
 		exists:           exists,
 		config:           config,
 		replicationProps: repl,
-		tenantKey:        tenantKey,
 	}
 }
 
@@ -101,7 +99,7 @@ func validateClass(class string) error {
 
 // ValidateSingleRef validates a single ref based on location URL and existence of the object in the database
 func (v *Validator) ValidateSingleRef(ctx context.Context, cref *models.SingleRef,
-	errorVal string,
+	errorVal string, tenant string,
 ) error {
 	ref, err := crossref.ParseSingleRef(cref)
 	if err != nil {
@@ -113,7 +111,7 @@ func (v *Validator) ValidateSingleRef(ctx context.Context, cref *models.SingleRe
 	}
 
 	// locally check for object existence
-	ok, err := v.exists(ctx, ref.Class, ref.TargetID, v.replicationProps, v.tenantKey)
+	ok, err := v.exists(ctx, ref.Class, ref.TargetID, v.replicationProps, tenant)
 	if err != nil {
 		return err
 	}
@@ -125,14 +123,14 @@ func (v *Validator) ValidateSingleRef(ctx context.Context, cref *models.SingleRe
 }
 
 func (v *Validator) ValidateMultipleRef(ctx context.Context, refs models.MultipleRef,
-	errorVal string,
+	errorVal string, tenant string,
 ) error {
 	if refs == nil {
 		return nil
 	}
 
 	for _, ref := range refs {
-		err := v.ValidateSingleRef(ctx, ref, errorVal)
+		err := v.ValidateSingleRef(ctx, ref, errorVal, tenant)
 		if err != nil {
 			return err
 		}
diff --git a/usecases/objects/validation/properties_validation.go b/usecases/objects/validation/properties_validation.go
index b397b19305..af86e5d504 100644
--- a/usecases/objects/validation/properties_validation.go
+++ b/usecases/objects/validation/properties_validation.go
@@ -72,15 +72,6 @@ func (v *Validator) properties(ctx context.Context, class *models.Class,
 			continue // nil values are removed and filtered out
 		}
 
-		mt := class.MultiTenancyConfig
-		if mt != nil && existingObject != nil && propertyKey == mt.TenantKey {
-			beforeKey := existingObject.Properties.(map[string]interface{})[mt.TenantKey]
-			afterKey := isp.(map[string]interface{})[mt.TenantKey]
-			if beforeKey != afterKey {
-				return fmt.Errorf("tenant key %q is immutable", mt.TenantKey)
-			}
-		}
-
 		// properties in the class are saved with lower case first letter
 		propertyKeyLowerCase := strings.ToLower(propertyKey[:1])
 		if len(propertyKey) > 1 {
@@ -463,7 +454,7 @@ func (v *Validator) parseAndValidateSingleRef(ctx context.Context, propertyName
 		return nil, fmt.Errorf("invalid reference: %s", err)
 	}
 	errVal := fmt.Sprintf("'cref' %s:%s", className, propertyName)
-	err = v.ValidateSingleRef(ctx, ref.SingleRef(), errVal)
+	err = v.ValidateSingleRef(ctx, ref.SingleRef(), errVal, "")
 	if err != nil {
 		return nil, err
 	}
diff --git a/usecases/objects/vector.go b/usecases/objects/vector.go
index 11097f0658..7ba6a9d413 100644
--- a/usecases/objects/vector.go
+++ b/usecases/objects/vector.go
@@ -44,7 +44,7 @@ func (m *Manager) updateRefVector(ctx context.Context, principal *models.Princip
 				className, id, err)
 		}
 
-		if err := m.vectorRepo.PutObject(ctx, obj, obj.Vector, nil, ""); err != nil {
+		if err := m.vectorRepo.PutObject(ctx, obj, obj.Vector, nil); err != nil {
 			return fmt.Errorf("put object: %w", err)
 		}
 
diff --git a/usecases/schema/add.go b/usecases/schema/add.go
index 54156a5fac..d57fc3527a 100644
--- a/usecases/schema/add.go
+++ b/usecases/schema/add.go
@@ -37,9 +37,6 @@ import (
 	"github.com/weaviate/weaviate/usecases/sharding"
 )
 
-var errInvalidTenantKey = "invalid multiTenancyConfig.tenantKey %q. " +
-	"tenantKey must be 'text' or 'uuid'"
-
 // AddClass to the schema
 func (m *Manager) AddClass(ctx context.Context, principal *models.Principal,
 	class *models.Class,
@@ -97,11 +94,6 @@ func (m *Manager) RestoreClass(ctx context.Context, d *backup.ClassDescriptor) e
 		return err
 	}
 
-	err = m.parseMultiTenancyConfig(ctx, class)
-	if err != nil {
-		return err
-	}
-
 	err = m.parseVectorIndexConfig(ctx, class)
 	if err != nil {
 		return err
@@ -146,9 +138,10 @@ func (m *Manager) addClass(ctx context.Context, class *models.Class,
 
 	class.Class = schema.UppercaseClassName(class.Class)
 	class.Properties = schema.LowercaseAllPropertyNames(class.Properties)
-
 	if class.ShardingConfig != nil && class.MultiTenancyConfig != nil {
 		return nil, fmt.Errorf("cannot have both shardingConfig and multiTenancyConfig")
+	} else if class.MultiTenancyConfig != nil {
+		class.ShardingConfig = sharding.Config{DesiredCount: 0} // tenant shards will be created dynamically
 	}
 
 	m.setClassDefaults(class)
@@ -164,11 +157,6 @@ func (m *Manager) addClass(ctx context.Context, class *models.Class,
 		return nil, err
 	}
 
-	err = m.parseMultiTenancyConfig(ctx, class)
-	if err != nil {
-		return nil, err
-	}
-
 	err = m.parseVectorIndexConfig(ctx, class)
 	if err != nil {
 		return nil, err
@@ -482,35 +470,6 @@ func (m *Manager) parseShardingConfig(ctx context.Context,
 	return nil
 }
 
-func (m *Manager) parseMultiTenancyConfig(ctx context.Context, class *models.Class) error {
-	if class.ShardingConfig == nil {
-		if class.MultiTenancyConfig.TenantKey == "" {
-			return fmt.Errorf("multiTenancyConfig.tenantKey is required")
-		}
-		for _, prop := range class.Properties {
-			if prop.Name == class.MultiTenancyConfig.TenantKey {
-				if len(prop.DataType) != 1 {
-					return fmt.Errorf(errInvalidTenantKey, prop.Name)
-				}
-				if prop.DataType[0] == schema.DataTypeText.String() ||
-					prop.DataType[0] == schema.DataTypeUUID.String() {
-					class.ShardingConfig = sharding.Config{
-						// tenant shards will be created dynamically
-						DesiredCount: 0,
-					}
-					return nil
-				} else {
-					return fmt.Errorf(errInvalidTenantKey, prop.Name)
-				}
-			}
-		}
-		return fmt.Errorf(
-			"no class property found for multiTenancyConfig.tenantKey %q",
-			class.MultiTenancyConfig.TenantKey)
-	}
-	return nil
-}
-
 func setInvertedConfigDefaults(class *models.Class) {
 	if class.InvertedIndexConfig == nil {
 		class.InvertedIndexConfig = &models.InvertedIndexConfig{}
diff --git a/usecases/schema/tenant.go b/usecases/schema/tenant.go
index f569906def..084c683075 100644
--- a/usecases/schema/tenant.go
+++ b/usecases/schema/tenant.go
@@ -215,5 +215,5 @@ func (m *Manager) onDeleteTenants(ctx context.Context, class *models.Class, req
 }
 
 func isMultiTenancyEnabled(cfg *models.MultiTenancyConfig) bool {
-	return cfg != nil && cfg.Enabled && cfg.TenantKey != ""
+	return cfg != nil && cfg.Enabled
 }


Test patch:
diff --git a/adapters/handlers/rest/handlers_objects_test.go b/adapters/handlers/rest/handlers_objects_test.go
index b1c72402c9..19cb9a8e62 100644
--- a/adapters/handlers/rest/handlers_objects_test.go
+++ b/adapters/handlers/rest/handlers_objects_test.go
@@ -1054,7 +1054,7 @@ func (f *fakeManager) HeadObject(context.Context, *models.Principal,
 }
 
 func (f *fakeManager) AddObject(_ context.Context, _ *models.Principal,
-	object *models.Object, _ *additional.ReplicationProperties, _ string,
+	object *models.Object, _ *additional.ReplicationProperties,
 ) (*models.Object, error) {
 	return object, nil
 }
@@ -1092,13 +1092,13 @@ func (f *fakeManager) Query(_ context.Context,
 }
 
 func (f *fakeManager) UpdateObject(_ context.Context, _ *models.Principal, _ string,
-	_ strfmt.UUID, updates *models.Object, _ *additional.ReplicationProperties, _ string,
+	_ strfmt.UUID, updates *models.Object, _ *additional.ReplicationProperties,
 ) (*models.Object, error) {
 	return updates, f.updateObjectErr
 }
 
 func (f *fakeManager) MergeObject(_ context.Context, _ *models.Principal,
-	_ *models.Object, _ *additional.ReplicationProperties, _ string,
+	_ *models.Object, _ *additional.ReplicationProperties,
 ) *uco.Error {
 	return f.patchObjectReturn
 }
diff --git a/adapters/repos/db/aggregations_integration_test.go b/adapters/repos/db/aggregations_integration_test.go
index e1755f68c3..d24619b1e0 100644
--- a/adapters/repos/db/aggregations_integration_test.go
+++ b/adapters/repos/db/aggregations_integration_test.go
@@ -154,7 +154,7 @@ func prepareCompanyTestSchemaAndData(repo *DB,
 						Properties: schema,
 					}
 					require.Nil(t,
-						repo.PutObject(context.Background(), &fixture, []float32{0.1, 0.2, 0.01, 0.2}, nil, ""))
+						repo.PutObject(context.Background(), &fixture, []float32{0.1, 0.2, 0.01, 0.2}, nil))
 				})
 			}
 		})
@@ -170,7 +170,7 @@ func prepareCompanyTestSchemaAndData(repo *DB,
 						}
 
 						require.Nil(t,
-							repo.PutObject(context.Background(), &fixture, []float32{0.1, 0.1, 0.1, 0.1}, nil, ""))
+							repo.PutObject(context.Background(), &fixture, []float32{0.1, 0.1, 0.1, 0.1}, nil))
 					})
 				}
 			}
@@ -185,7 +185,7 @@ func prepareCompanyTestSchemaAndData(repo *DB,
 						Properties: schema,
 					}
 					require.Nil(t,
-						repo.PutObject(context.Background(), &fixture, []float32{0.1, 0.1, 0.1, 0.1}, nil, ""))
+						repo.PutObject(context.Background(), &fixture, []float32{0.1, 0.1, 0.1, 0.1}, nil))
 				})
 			}
 		})
@@ -199,7 +199,7 @@ func prepareCompanyTestSchemaAndData(repo *DB,
 						Properties: schema,
 					}
 					require.Nil(t,
-						repo.PutObject(context.Background(), &fixture, []float32{0.1, 0.1, 0.1, 0.1}, nil, ""))
+						repo.PutObject(context.Background(), &fixture, []float32{0.1, 0.1, 0.1, 0.1}, nil))
 				})
 			}
 		})
diff --git a/adapters/repos/db/backup_integration_test.go b/adapters/repos/db/backup_integration_test.go
index 650b66b822..3d95b2676f 100644
--- a/adapters/repos/db/backup_integration_test.go
+++ b/adapters/repos/db/backup_integration_test.go
@@ -54,7 +54,7 @@ func TestBackup_DBLevel(t *testing.T) {
 				LastUpdateTimeUnix: now.UnixNano(),
 				Vector:             []float32{1, 2, 3},
 				VectorWeights:      nil,
-			}, []float32{1, 2, 3}, nil, ""))
+			}, []float32{1, 2, 3}, nil))
 		})
 
 		expectedNodeName := "node1"
@@ -154,7 +154,7 @@ func TestBackup_DBLevel(t *testing.T) {
 				LastUpdateTimeUnix: now.UnixNano(),
 				Vector:             []float32{1, 2, 3},
 				VectorWeights:      nil,
-			}, []float32{1, 2, 3}, nil, ""))
+			}, []float32{1, 2, 3}, nil))
 		})
 
 		t.Run("fail with expired context", func(t *testing.T) {
diff --git a/adapters/repos/db/batch_integration_test.go b/adapters/repos/db/batch_integration_test.go
index 63eb96dc4e..2e8b89a16e 100644
--- a/adapters/repos/db/batch_integration_test.go
+++ b/adapters/repos/db/batch_integration_test.go
@@ -377,7 +377,7 @@ func testBatchImportObjectsNoVector(repo *DB) func(t *testing.T) {
 			}
 
 			t.Run("can import", func(t *testing.T) {
-				batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil, "")
+				batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil)
 				require.Nil(t, err)
 
 				assert.Nil(t, batchRes[0].Err)
@@ -413,7 +413,7 @@ func simpleInsertObjects(t *testing.T, repo *DB, class string, count int) {
 		}
 	}
 
-	repo.BatchPutObjects(context.Background(), batch, nil, "")
+	repo.BatchPutObjects(context.Background(), batch, nil)
 }
 
 func testBatchImportObjects(repo *DB) func(t *testing.T) {
@@ -462,7 +462,7 @@ func testBatchImportObjects(repo *DB) func(t *testing.T) {
 			}
 
 			t.Run("can import", func(t *testing.T) {
-				batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil, "")
+				batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil)
 				require.Nil(t, err)
 
 				assert.Nil(t, batchRes[0].Err)
@@ -546,7 +546,7 @@ func testBatchImportObjects(repo *DB) func(t *testing.T) {
 			}
 
 			t.Run("can import", func(t *testing.T) {
-				batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil, "")
+				batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil)
 				require.Nil(t, err, "there shouldn't be an overall error, only inividual ones")
 
 				t.Run("element errors are marked correctly", func(t *testing.T) {
@@ -607,7 +607,7 @@ func testBatchImportObjects(repo *DB) func(t *testing.T) {
 				}
 
 				t.Run("can import", func(t *testing.T) {
-					batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil, "")
+					batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil)
 					require.Nil(t, err)
 
 					assert.Nil(t, batchRes[0].Err)
@@ -698,7 +698,7 @@ func testBatchImportObjects(repo *DB) func(t *testing.T) {
 			}
 
 			t.Run("can import", func(t *testing.T) {
-				batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil, "")
+				batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil)
 				require.Nil(t, err, "there shouldn't be an overall error, only inividual ones")
 
 				t.Run("element errors are marked correctly", func(t *testing.T) {
@@ -755,7 +755,7 @@ func testBatchImportObjects(repo *DB) func(t *testing.T) {
 				ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond)
 				defer cancel()
 
-				batchRes, err := repo.BatchPutObjects(ctx, batch, nil, "")
+				batchRes, err := repo.BatchPutObjects(ctx, batch, nil)
 				require.Nil(t, err, "there shouldn't be an overall error, only inividual ones")
 
 				t.Run("some elements have error'd due to context", func(t *testing.T) {
@@ -812,7 +812,7 @@ func testBatchImportGeoObjects(repo *DB) func(t *testing.T) {
 					}
 				}
 
-				res, err := repo.BatchPutObjects(context.Background(), batch, nil, "")
+				res, err := repo.BatchPutObjects(context.Background(), batch, nil)
 				require.Nil(t, err)
 				assertAllItemsErrorFree(t, res)
 			}
@@ -894,7 +894,7 @@ func testBatchImportGeoObjects(repo *DB) func(t *testing.T) {
 					}
 				}
 
-				res, err := repo.BatchPutObjects(context.Background(), batch, nil, "")
+				res, err := repo.BatchPutObjects(context.Background(), batch, nil)
 				require.Nil(t, err)
 				assertAllItemsErrorFree(t, res)
 			}
diff --git a/adapters/repos/db/batch_reference_integration_test.go b/adapters/repos/db/batch_reference_integration_test.go
index d3b3f2fee0..381cc0b3c0 100644
--- a/adapters/repos/db/batch_reference_integration_test.go
+++ b/adapters/repos/db/batch_reference_integration_test.go
@@ -10,7 +10,6 @@
 //
 
 //go:build integrationTest
-// +build integrationTest
 
 package db
 
@@ -110,7 +109,7 @@ func Test_AddingReferencesInBatches(t *testing.T) {
 			Properties: map[string]interface{}{
 				"name": "source item",
 			},
-		}, []float32{0.5}, nil, "")
+		}, []float32{0.5}, nil)
 		require.Nil(t, err)
 
 		targets := []strfmt.UUID{target1, target2, target3, target4}
@@ -122,7 +121,7 @@ func Test_AddingReferencesInBatches(t *testing.T) {
 				Properties: map[string]interface{}{
 					"name": fmt.Sprintf("target item %d", i),
 				},
-			}, []float32{0.7}, nil, "")
+			}, []float32{0.7}, nil)
 			require.Nil(t, err)
 		}
 	})
@@ -176,7 +175,7 @@ func Test_AddingReferencesInBatches(t *testing.T) {
 				OriginalIndex: i,
 			}
 		}
-		_, err = repo.AddBatchReferences(context.Background(), refs, nil, "")
+		_, err = repo.AddBatchReferences(context.Background(), refs, nil)
 		assert.Nil(t, err)
 	})
 
@@ -251,7 +250,7 @@ func Test_AddingReferencesInBatches(t *testing.T) {
 				OriginalIndex: 3*i + 2,
 			}
 		}
-		batchRefs, err := repo.AddBatchReferences(context.Background(), refs, nil, "")
+		batchRefs, err := repo.AddBatchReferences(context.Background(), refs, nil)
 		assert.Nil(t, err)
 		require.Len(t, batchRefs, 6)
 		assert.Nil(t, batchRefs[0].Err)
diff --git a/adapters/repos/db/bm25f_test.go b/adapters/repos/db/bm25f_test.go
index 43d02b7171..b4c76eaa67 100644
--- a/adapters/repos/db/bm25f_test.go
+++ b/adapters/repos/db/bm25f_test.go
@@ -145,7 +145,7 @@ func SetupClass(t require.TestingT, repo *DB, schemaGetter *fakeSchemaGetter, lo
 		obj := &models.Object{Class: "MyClass", ID: id, Properties: data, CreationTimeUnix: 1565612833955, LastUpdateTimeUnix: 10000020}
 		vector := []float32{1, 3, 5, 0.4}
 		//{title: "Our journey to BM25F", description: " This is how we get to BM25F"}}
-		err := repo.PutObject(context.Background(), obj, vector, nil, "")
+		err := repo.PutObject(context.Background(), obj, vector, nil)
 		require.Nil(t, err)
 	}
 }
@@ -197,7 +197,7 @@ func SetupClassForFilterScoringTest(t require.TestingT, repo *DB, schemaGetter *
 
 		obj := &models.Object{Class: "FilterClass", ID: id, Properties: data, CreationTimeUnix: 1565612833955, LastUpdateTimeUnix: 10000020}
 		vector := []float32{1, 3, 5, 0.4}
-		err := repo.PutObject(context.Background(), obj, vector, nil, "")
+		err := repo.PutObject(context.Background(), obj, vector, nil)
 		require.Nil(t, err)
 	}
 }
@@ -836,7 +836,7 @@ func SetupClassDocuments(t require.TestingT, repo *DB, schemaGetter *fakeSchemaG
 		obj := &models.Object{Class: className, ID: id, Properties: data, CreationTimeUnix: 1565612833955, LastUpdateTimeUnix: 10000020}
 		vector := []float32{1, 3, 5, 0.4}
 		//{title: "Our journey to BM25F", description: " This is how we get to BM25F"}}
-		err := repo.PutObject(context.Background(), obj, vector, nil, "")
+		err := repo.PutObject(context.Background(), obj, vector, nil)
 		require.Nil(t, err)
 	}
 	return className
@@ -971,7 +971,7 @@ func MultiPropClass(t require.TestingT, repo *DB, schemaGetter *fakeSchemaGetter
 
 		obj := &models.Object{Class: className, ID: id, Properties: data, CreationTimeUnix: 1565612833955, LastUpdateTimeUnix: 10000020}
 		vector := []float32{1, 3, 5, 0.4}
-		err := repo.PutObject(context.Background(), obj, vector, nil, "")
+		err := repo.PutObject(context.Background(), obj, vector, nil)
 		require.Nil(t, err)
 	}
 	return className
diff --git a/adapters/repos/db/classification_integration_test.go b/adapters/repos/db/classification_integration_test.go
index ff1cd274b6..c863e51901 100644
--- a/adapters/repos/db/classification_integration_test.go
+++ b/adapters/repos/db/classification_integration_test.go
@@ -61,7 +61,7 @@ func TestClassifications(t *testing.T) {
 	t.Run("importing categories", func(t *testing.T) {
 		for _, res := range classificationTestCategories() {
 			thing := res.Object()
-			err := repo.PutObject(context.Background(), thing, res.Vector, nil, "")
+			err := repo.PutObject(context.Background(), thing, res.Vector, nil)
 			require.Nil(t, err)
 		}
 	})
@@ -69,7 +69,7 @@ func TestClassifications(t *testing.T) {
 	t.Run("importing articles", func(t *testing.T) {
 		for _, res := range classificationTestArticles() {
 			thing := res.Object()
-			err := repo.PutObject(context.Background(), thing, res.Vector, nil, "")
+			err := repo.PutObject(context.Background(), thing, res.Vector, nil)
 			require.Nil(t, err)
 		}
 	})
diff --git a/adapters/repos/db/clusterintegrationtest/backup_coordinator_integration_test.go b/adapters/repos/db/clusterintegrationtest/backup_coordinator_integration_test.go
index 0b677123d7..abf2a0214b 100644
--- a/adapters/repos/db/clusterintegrationtest/backup_coordinator_integration_test.go
+++ b/adapters/repos/db/clusterintegrationtest/backup_coordinator_integration_test.go
@@ -82,7 +82,7 @@ func TestDistributedBackups(t *testing.T) {
 			for _, obj := range data {
 				node := nodes[rnd.Intn(len(nodes))]
 
-				err := node.repo.PutObject(context.Background(), obj, obj.Vector, nil, "")
+				err := node.repo.PutObject(context.Background(), obj, obj.Vector, nil)
 				require.Nil(t, err)
 			}
 		})
@@ -91,7 +91,7 @@ func TestDistributedBackups(t *testing.T) {
 			for _, obj := range refData {
 				node := nodes[rnd.Intn(len(nodes))]
 
-				err := node.repo.PutObject(context.Background(), obj, obj.Vector, nil, "")
+				err := node.repo.PutObject(context.Background(), obj, obj.Vector, nil)
 				require.Nil(t, err)
 			}
 		})
diff --git a/adapters/repos/db/clusterintegrationtest/cluster_integration_test.go b/adapters/repos/db/clusterintegrationtest/cluster_integration_test.go
index 5acf3f960f..31f3687527 100644
--- a/adapters/repos/db/clusterintegrationtest/cluster_integration_test.go
+++ b/adapters/repos/db/clusterintegrationtest/cluster_integration_test.go
@@ -10,7 +10,6 @@
 //
 
 //go:build integrationTest
-// +build integrationTest
 
 package clusterintegrationtest
 
@@ -103,7 +102,7 @@ func testDistributed(t *testing.T, dirName string, rnd *rand.Rand, batch bool) {
 			node := nodes[rnd.Intn(len(nodes))]
 
 			batchObjs := dataAsBatch(data)
-			res, err := node.repo.BatchPutObjects(context.Background(), batchObjs, nil, "")
+			res, err := node.repo.BatchPutObjects(context.Background(), batchObjs, nil)
 			require.Nil(t, err)
 			for _, ind := range res {
 				require.Nil(t, ind.Err)
@@ -115,7 +114,7 @@ func testDistributed(t *testing.T, dirName string, rnd *rand.Rand, batch bool) {
 			node := nodes[rnd.Intn(len(nodes))]
 
 			batchObjs := dataAsBatchWithProps(refData, []string{"description"})
-			res, err := node.repo.BatchPutObjects(context.Background(), batchObjs, nil, "")
+			res, err := node.repo.BatchPutObjects(context.Background(), batchObjs, nil)
 			require.Nil(t, err)
 			for _, ind := range res {
 				require.Nil(t, ind.Err)
@@ -127,7 +126,7 @@ func testDistributed(t *testing.T, dirName string, rnd *rand.Rand, batch bool) {
 			node := nodes[rnd.Intn(len(nodes))]
 
 			batch := refsAsBatch(refData, "toFirst")
-			res, err := node.repo.AddBatchReferences(context.Background(), batch, nil, "")
+			res, err := node.repo.AddBatchReferences(context.Background(), batch, nil)
 			require.Nil(t, err)
 			for _, ind := range res {
 				require.Nil(t, ind.Err)
@@ -138,7 +137,7 @@ func testDistributed(t *testing.T, dirName string, rnd *rand.Rand, batch bool) {
 			for _, obj := range data {
 				node := nodes[rnd.Intn(len(nodes))]
 
-				err := node.repo.PutObject(context.Background(), obj, obj.Vector, nil, "")
+				err := node.repo.PutObject(context.Background(), obj, obj.Vector, nil)
 				require.Nil(t, err)
 			}
 		})
@@ -147,7 +146,7 @@ func testDistributed(t *testing.T, dirName string, rnd *rand.Rand, batch bool) {
 			for _, obj := range refData {
 				node := nodes[rnd.Intn(len(nodes))]
 
-				err := node.repo.PutObject(context.Background(), obj, obj.Vector, nil, "")
+				err := node.repo.PutObject(context.Background(), obj, obj.Vector, nil)
 				require.Nil(t, err)
 			}
 		})
diff --git a/adapters/repos/db/crud_deletion_integration_test.go b/adapters/repos/db/crud_deletion_integration_test.go
index 0727e79e29..abb48f6a04 100644
--- a/adapters/repos/db/crud_deletion_integration_test.go
+++ b/adapters/repos/db/crud_deletion_integration_test.go
@@ -60,7 +60,7 @@ func TestDeleteJourney(t *testing.T) {
 
 	t.Run("import some objects", func(t *testing.T) {
 		for _, res := range updateTestData() {
-			err := repo.PutObject(context.Background(), res.Object(), res.Vector, nil, "")
+			err := repo.PutObject(context.Background(), res.Object(), res.Vector, nil)
 			require.Nil(t, err)
 		}
 	})
diff --git a/adapters/repos/db/crud_integration_test.go b/adapters/repos/db/crud_integration_test.go
index 0b32e8c1c6..1d406c4e5c 100644
--- a/adapters/repos/db/crud_integration_test.go
+++ b/adapters/repos/db/crud_integration_test.go
@@ -162,7 +162,7 @@ func TestCRUD(t *testing.T) {
 		}
 		vector := []float32{1, 3, 5, 0.4}
 
-		err := repo.PutObject(context.Background(), thing, vector, nil, "")
+		err := repo.PutObject(context.Background(), thing, vector, nil)
 
 		assert.Nil(t, err)
 	})
@@ -185,7 +185,7 @@ func TestCRUD(t *testing.T) {
 		}
 		vector := []float32{1, 3, 5, 0.4}
 
-		err := repo.PutObject(context.Background(), thing, vector, nil, "")
+		err := repo.PutObject(context.Background(), thing, vector, nil)
 		assert.Equal(t,
 			fmt.Errorf("import into non-existing index for WrongClass"), err)
 	})
@@ -223,7 +223,7 @@ func TestCRUD(t *testing.T) {
 		}
 		vector := []float32{1, 3, 5, 0.4}
 
-		err := repo.PutObject(context.Background(), thing, vector, nil, "")
+		err := repo.PutObject(context.Background(), thing, vector, nil)
 		assert.Nil(t, err)
 	})
 
@@ -367,7 +367,7 @@ func TestCRUD(t *testing.T) {
 		}
 		vector := []float32{1, 3, 5, 0.4}
 
-		err := repo.PutObject(context.Background(), thing, vector, nil, "")
+		err := repo.PutObject(context.Background(), thing, vector, nil)
 		assert.Nil(t, err)
 	})
 
@@ -410,7 +410,7 @@ func TestCRUD(t *testing.T) {
 		}
 		vector := []float32{3, 1, 0.3, 12}
 
-		err := repo.PutObject(context.Background(), action, vector, nil, "")
+		err := repo.PutObject(context.Background(), action, vector, nil)
 
 		assert.Nil(t, err)
 	})
@@ -529,7 +529,7 @@ func TestCRUD(t *testing.T) {
 		}
 		vector := []float32{1, 3, 5, 0.4}
 
-		err := repo.PutObject(context.Background(), thing, vector, nil, "")
+		err := repo.PutObject(context.Background(), thing, vector, nil)
 
 		assert.Nil(t, err)
 	})
@@ -835,7 +835,7 @@ func TestCRUD(t *testing.T) {
 				},
 			}
 			vector := []float32{1.1, 1.3, 1.5, 1.4}
-			err := repo.PutObject(context.Background(), object, vector, nil, "")
+			err := repo.PutObject(context.Background(), object, vector, nil)
 			assert.Nil(t, err)
 		}
 		// run sorting tests
@@ -1096,7 +1096,7 @@ func TestCRUD(t *testing.T) {
 				}
 				createdActionIDs[i] = newID
 			}
-			batchObjResp, err := repo.BatchPutObjects(context.Background(), actionBatch, nil, "")
+			batchObjResp, err := repo.BatchPutObjects(context.Background(), actionBatch, nil)
 			require.Len(t, batchObjResp, numThings)
 			require.Nil(t, err)
 			for _, r := range batchObjResp {
@@ -1120,7 +1120,7 @@ func TestCRUD(t *testing.T) {
 				}
 				createdThingIDs[i] = newID
 			}
-			batchObjResp, err := repo.BatchPutObjects(context.Background(), thingBatch, nil, "")
+			batchObjResp, err := repo.BatchPutObjects(context.Background(), thingBatch, nil)
 			require.Len(t, batchObjResp, numThings)
 			require.Nil(t, err)
 			for _, r := range batchObjResp {
@@ -1147,7 +1147,7 @@ func TestCRUD(t *testing.T) {
 				}
 				refBatch[i] = ref
 			}
-			batchRefResp, err := repo.AddBatchReferences(context.Background(), refBatch, nil, "")
+			batchRefResp, err := repo.AddBatchReferences(context.Background(), refBatch, nil)
 			require.Nil(t, err)
 			require.Len(t, batchRefResp, numThings)
 			for _, r := range batchRefResp {
@@ -1229,7 +1229,7 @@ func TestCRUD(t *testing.T) {
 				Class:  "TheBestActionClass",
 				Vector: vec,
 			}
-			require.Nil(t, repo.PutObject(context.Background(), obj, vec, nil, ""))
+			require.Nil(t, repo.PutObject(context.Background(), obj, vec, nil))
 		})
 
 		t.Run("perform search with id filter", func(t *testing.T) {
@@ -1376,7 +1376,7 @@ func TestCRUD_Query(t *testing.T) {
 				},
 			}
 			vector := []float32{1.1, 1.3, 1.5, 1.4}
-			err := repo.PutObject(context.Background(), object, vector, nil, "")
+			err := repo.PutObject(context.Background(), object, vector, nil)
 			assert.Nil(t, err)
 		}
 		// toParams helper method
@@ -1575,7 +1575,7 @@ func Test_ImportWithoutVector_UpdateWithVectorLater(t *testing.T) {
 
 	t.Run("import individual objects without vector", func(t *testing.T) {
 		for i := 0; i < individual; i++ {
-			err := repo.PutObject(context.Background(), data[i], nil, nil, "") // nil vector !
+			err := repo.PutObject(context.Background(), data[i], nil, nil) // nil vector !
 			require.Nil(t, err)
 		}
 	})
@@ -1593,7 +1593,7 @@ func Test_ImportWithoutVector_UpdateWithVectorLater(t *testing.T) {
 			}
 		}
 
-		res, err := repo.BatchPutObjects(context.Background(), batch, nil, "")
+		res, err := repo.BatchPutObjects(context.Background(), batch, nil)
 		require.Nil(t, err)
 
 		for _, obj := range res {
@@ -1635,7 +1635,7 @@ func Test_ImportWithoutVector_UpdateWithVectorLater(t *testing.T) {
 			}
 
 			data[i].Vector = randomVector(r, 7)
-			err := repo.PutObject(context.Background(), data[i], data[i].Vector, nil, "")
+			err := repo.PutObject(context.Background(), data[i], data[i].Vector, nil)
 			require.Nil(t, err)
 		}
 	})
@@ -1748,7 +1748,7 @@ func TestVectorSearch_ByDistance(t *testing.T) {
 
 	t.Run("insert test objects", func(t *testing.T) {
 		for id, props := range tests {
-			err := repo.PutObject(context.Background(), &models.Object{Class: className, ID: id}, props.inputVec, nil, "")
+			err := repo.PutObject(context.Background(), &models.Object{Class: className, ID: id}, props.inputVec, nil)
 			require.Nil(t, err)
 		}
 	})
@@ -1884,7 +1884,7 @@ func TestVectorSearch_ByCertainty(t *testing.T) {
 
 	t.Run("insert test objects", func(t *testing.T) {
 		for id, props := range tests {
-			err := repo.PutObject(context.Background(), &models.Object{Class: className, ID: id}, props.inputVec, nil, "")
+			err := repo.PutObject(context.Background(), &models.Object{Class: className, ID: id}, props.inputVec, nil)
 			require.Nil(t, err)
 		}
 	})
@@ -1993,7 +1993,7 @@ func Test_PutPatchRestart(t *testing.T) {
 			ID:         testID,
 			Class:      testClass.Class,
 			Properties: map[string]interface{}{"description": "test object init"},
-		}, testVec, nil, "")
+		}, testVec, nil)
 		require.Nil(t, err)
 	})
 
@@ -2005,7 +2005,7 @@ func Test_PutPatchRestart(t *testing.T) {
 				Properties: map[string]interface{}{
 					"description": fmt.Sprintf("test object, put #%d", i+1),
 				},
-			}, nil, nil, "")
+			}, nil, nil)
 			require.Nil(t, err)
 
 			err = repo.Merge(ctx, objects.MergeDocument{
@@ -2149,8 +2149,8 @@ func TestCRUDWithEmptyArrays(t *testing.T) {
 			},
 		}
 
-		assert.Nil(t, repo.PutObject(context.Background(), obj1, []float32{1, 3, 5, 0.4}, nil, ""))
-		assert.Nil(t, repo.PutObject(context.Background(), obj2, []float32{1, 3, 5, 0.4}, nil, ""))
+		assert.Nil(t, repo.PutObject(context.Background(), obj1, []float32{1, 3, 5, 0.4}, nil))
+		assert.Nil(t, repo.PutObject(context.Background(), obj2, []float32{1, 3, 5, 0.4}, nil))
 
 		res, err := repo.ObjectByID(context.Background(), objID, nil, additional.Properties{}, "")
 		require.Nil(t, err)
@@ -2166,7 +2166,7 @@ func TestCRUDWithEmptyArrays(t *testing.T) {
 				"stringProp": "string prop value",
 			},
 		}
-		assert.Nil(t, repo.PutObject(context.Background(), objRef, []float32{1, 3, 5, 0.4}, nil, ""))
+		assert.Nil(t, repo.PutObject(context.Background(), objRef, []float32{1, 3, 5, 0.4}, nil))
 
 		obj1ID := strfmt.UUID("a0b55b05-bc5b-4cc9-b646-1452d1390a62")
 		obj1 := &models.Object{
@@ -2201,8 +2201,8 @@ func TestCRUDWithEmptyArrays(t *testing.T) {
 			},
 		}
 
-		assert.Nil(t, repo.PutObject(context.Background(), obj1, []float32{1, 3, 5, 0.4}, nil, ""))
-		assert.Nil(t, repo.PutObject(context.Background(), obj2, []float32{1, 3, 5, 0.4}, nil, ""))
+		assert.Nil(t, repo.PutObject(context.Background(), obj1, []float32{1, 3, 5, 0.4}, nil))
+		assert.Nil(t, repo.PutObject(context.Background(), obj2, []float32{1, 3, 5, 0.4}, nil))
 
 		res, err := repo.Object(context.Background(), classNameWithRefs, obj1ID, nil,
 			additional.Properties{}, nil, "")
@@ -2287,7 +2287,7 @@ func TestOverwriteObjects(t *testing.T) {
 	}
 
 	t.Run("insert stale object", func(t *testing.T) {
-		err := repo.PutObject(context.Background(), stale, stale.Vector, nil, "")
+		err := repo.PutObject(context.Background(), stale, stale.Vector, nil)
 		require.Nil(t, err)
 	})
 
@@ -2381,9 +2381,9 @@ func TestIndexDigestObjects(t *testing.T) {
 	}
 
 	t.Run("insert test objects", func(t *testing.T) {
-		err := repo.PutObject(context.Background(), obj1, obj1.Vector, nil, "")
+		err := repo.PutObject(context.Background(), obj1, obj1.Vector, nil)
 		require.Nil(t, err)
-		err = repo.PutObject(context.Background(), obj2, obj2.Vector, nil, "")
+		err = repo.PutObject(context.Background(), obj2, obj2.Vector, nil)
 		require.Nil(t, err)
 	})
 
@@ -2482,7 +2482,7 @@ func TestIndexDifferentVectorLength(t *testing.T) {
 			Class:  class.Class,
 			Vector: nil,
 		}
-		require.Nil(t, repo.PutObject(context.Background(), objNil, objNil.Vector, nil, ""))
+		require.Nil(t, repo.PutObject(context.Background(), objNil, objNil.Vector, nil))
 		found, err := repo.Object(context.Background(), class.Class, objNil.ID, nil,
 			additional.Properties{}, nil, "")
 		require.Nil(t, err)
@@ -2496,7 +2496,7 @@ func TestIndexDifferentVectorLength(t *testing.T) {
 			Class:  class.Class,
 			Vector: []float32{1, 2, 3},
 		}
-		require.Nil(t, repo.PutObject(context.Background(), obj1, obj1.Vector, nil, ""))
+		require.Nil(t, repo.PutObject(context.Background(), obj1, obj1.Vector, nil))
 	})
 
 	t.Run("Add object with different vector length", func(t *testing.T) {
@@ -2505,7 +2505,7 @@ func TestIndexDifferentVectorLength(t *testing.T) {
 			Class:  class.Class,
 			Vector: []float32{1, 2, 3, 4},
 		}
-		require.NotNil(t, repo.PutObject(context.Background(), obj2, obj2.Vector, nil, ""))
+		require.NotNil(t, repo.PutObject(context.Background(), obj2, obj2.Vector, nil))
 		found, err := repo.Object(context.Background(), class.Class, obj2.ID, nil,
 			additional.Properties{}, nil, "")
 		require.Nil(t, err)
@@ -2548,7 +2548,7 @@ func TestIndexDifferentVectorLength(t *testing.T) {
 			Class:  class.Class,
 			Vector: nil,
 		}
-		require.Nil(t, repo.PutObject(context.Background(), obj2Nil, obj2Nil.Vector, nil, ""))
+		require.Nil(t, repo.PutObject(context.Background(), obj2Nil, obj2Nil.Vector, nil))
 		found, err := repo.Object(context.Background(), class.Class, obj2Nil.ID, nil,
 			additional.Properties{}, nil, "")
 		require.Nil(t, err)
diff --git a/adapters/repos/db/crud_noindex_property_integration_test.go b/adapters/repos/db/crud_noindex_property_integration_test.go
index 3818a0b5e3..cb5fe0b385 100644
--- a/adapters/repos/db/crud_noindex_property_integration_test.go
+++ b/adapters/repos/db/crud_noindex_property_integration_test.go
@@ -92,7 +92,7 @@ func TestCRUD_NoIndexProp(t *testing.T) {
 			},
 		}
 		vector := []float32{1, 3, 5, 0.4}
-		err := repo.PutObject(context.Background(), thing, vector, nil, "")
+		err := repo.PutObject(context.Background(), thing, vector, nil)
 
 		assert.Nil(t, err)
 	})
diff --git a/adapters/repos/db/crud_null_objects_integration_test.go b/adapters/repos/db/crud_null_objects_integration_test.go
index 7251a1c367..bbcf4fb46e 100644
--- a/adapters/repos/db/crud_null_objects_integration_test.go
+++ b/adapters/repos/db/crud_null_objects_integration_test.go
@@ -117,14 +117,14 @@ func TestNullArrayClass(t *testing.T) {
 			}
 
 			if name == names[0] {
-				assert.Nil(t, repo.PutObject(context.Background(), arrayObjNil, []float32{1}, nil, ""))
-				assert.Nil(t, repo.PutObject(context.Background(), arrayObjEmpty, []float32{1}, nil, ""))
+				assert.Nil(t, repo.PutObject(context.Background(), arrayObjNil, []float32{1}, nil))
+				assert.Nil(t, repo.PutObject(context.Background(), arrayObjEmpty, []float32{1}, nil))
 
 			} else {
 				batch := make([]objects.BatchObject, 2)
 				batch[0] = objects.BatchObject{Object: arrayObjNil, UUID: arrayObjNil.ID}
 				batch[1] = objects.BatchObject{Object: arrayObjEmpty, UUID: arrayObjEmpty.ID}
-				_, err := repo.BatchPutObjects(context.Background(), batch, nil, "")
+				_, err := repo.BatchPutObjects(context.Background(), batch, nil)
 				assert.Nil(t, err)
 			}
 
diff --git a/adapters/repos/db/crud_references_integration_test.go b/adapters/repos/db/crud_references_integration_test.go
index f919bb0e22..6e02ca43f7 100644
--- a/adapters/repos/db/crud_references_integration_test.go
+++ b/adapters/repos/db/crud_references_integration_test.go
@@ -208,7 +208,7 @@ func TestNestedReferences(t *testing.T) {
 
 		for _, thing := range objects {
 			t.Run(fmt.Sprintf("add %s", thing.ID), func(t *testing.T) {
-				err := repo.PutObject(context.Background(), &thing, []float32{1, 2, 3, 4, 5, 6, 7}, nil, "")
+				err := repo.PutObject(context.Background(), &thing, []float32{1, 2, 3, 4, 5, 6, 7}, nil)
 				require.Nil(t, err)
 			})
 		}
@@ -378,7 +378,7 @@ func TestNestedReferences(t *testing.T) {
 			CreationTimeUnix: 1566464912,
 		}
 
-		err := repo.PutObject(context.Background(), &newPlace, []float32{1, 2, 3, 4, 5, 6, 7}, nil, "")
+		err := repo.PutObject(context.Background(), &newPlace, []float32{1, 2, 3, 4, 5, 6, 7}, nil)
 		require.Nil(t, err)
 	})
 }
@@ -592,7 +592,7 @@ func Test_AddingReferenceOneByOne(t *testing.T) {
 			Properties: map[string]interface{}{
 				"name": "source item",
 			},
-		}, []float32{0.5}, nil, "")
+		}, []float32{0.5}, nil)
 		require.Nil(t, err)
 
 		err = repo.PutObject(context.Background(), &models.Object{
@@ -601,7 +601,7 @@ func Test_AddingReferenceOneByOne(t *testing.T) {
 			Properties: map[string]interface{}{
 				"name": "target item",
 			},
-		}, []float32{0.5}, nil, "")
+		}, []float32{0.5}, nil)
 		require.Nil(t, err)
 
 		err = repo.PutObject(context.Background(), &models.Object{
@@ -610,7 +610,7 @@ func Test_AddingReferenceOneByOne(t *testing.T) {
 			Properties: map[string]interface{}{
 				"name": "another target item",
 			},
-		}, []float32{0.5}, nil, "")
+		}, []float32{0.5}, nil)
 		require.Nil(t, err)
 	})
 
diff --git a/adapters/repos/db/crud_references_multiple_types_integration_test.go b/adapters/repos/db/crud_references_multiple_types_integration_test.go
index 78d19797c3..40d730d1f4 100644
--- a/adapters/repos/db/crud_references_multiple_types_integration_test.go
+++ b/adapters/repos/db/crud_references_multiple_types_integration_test.go
@@ -191,7 +191,7 @@ func TestMultipleCrossRefTypes(t *testing.T) {
 
 		for _, thing := range objects {
 			t.Run(fmt.Sprintf("add %s", thing.ID), func(t *testing.T) {
-				err := repo.PutObject(context.Background(), &thing, []float32{1, 2, 3, 4, 5, 6, 7}, nil, "")
+				err := repo.PutObject(context.Background(), &thing, []float32{1, 2, 3, 4, 5, 6, 7}, nil)
 				require.Nil(t, err)
 			})
 		}
diff --git a/adapters/repos/db/crud_update_integration_test.go b/adapters/repos/db/crud_update_integration_test.go
index 93cef4edc7..d1722a4e5f 100644
--- a/adapters/repos/db/crud_update_integration_test.go
+++ b/adapters/repos/db/crud_update_integration_test.go
@@ -69,7 +69,7 @@ func TestUpdateJourney(t *testing.T) {
 
 	t.Run("import some objects", func(t *testing.T) {
 		for _, res := range updateTestData() {
-			err := repo.PutObject(context.Background(), res.Object(), res.Vector, nil, "")
+			err := repo.PutObject(context.Background(), res.Object(), res.Vector, nil)
 			require.Nil(t, err)
 		}
 
@@ -153,7 +153,7 @@ func TestUpdateJourney(t *testing.T) {
 			old, err := repo.ObjectByID(context.Background(), id, search.SelectProperties{}, additional.Properties{}, "")
 			require.Nil(t, err)
 
-			err = repo.PutObject(context.Background(), old.Object(), updatedVec, nil, "")
+			err = repo.PutObject(context.Background(), old.Object(), updatedVec, nil)
 			require.Nil(t, err)
 
 			tracker := getTracker(repo, "UpdateTestClass")
@@ -216,7 +216,7 @@ func TestUpdateJourney(t *testing.T) {
 			require.Nil(t, err)
 
 			old.Schema.(map[string]interface{})["intProp"] = int64(21)
-			err = repo.PutObject(context.Background(), old.Object(), updatedVec, nil, "")
+			err = repo.PutObject(context.Background(), old.Object(), updatedVec, nil)
 			require.Nil(t, err)
 
 			tracker := getTracker(repo, "UpdateTestClass")
diff --git a/adapters/repos/db/delete_filter_integration_test.go b/adapters/repos/db/delete_filter_integration_test.go
index aef314d70c..ef73437f80 100644
--- a/adapters/repos/db/delete_filter_integration_test.go
+++ b/adapters/repos/db/delete_filter_integration_test.go
@@ -93,7 +93,7 @@ func Test_FilterSearchesOnDeletedDocIDsWithLimits(t *testing.T) {
 				Vector: []float32{0.1},
 			}
 
-			err := repo.PutObject(context.Background(), things[i], things[i].Vector, nil, "")
+			err := repo.PutObject(context.Background(), things[i], things[i].Vector, nil)
 			require.Nil(t, err)
 		}
 	})
@@ -106,7 +106,7 @@ func Test_FilterSearchesOnDeletedDocIDsWithLimits(t *testing.T) {
 		for i := 0; i < 5; i++ {
 			things[i].Properties.(map[string]interface{})["unrelatedProp"] = "updatedValue"
 
-			err := repo.PutObject(context.Background(), things[i], things[i].Vector, nil, "")
+			err := repo.PutObject(context.Background(), things[i], things[i].Vector, nil)
 			require.Nil(t, err)
 		}
 	})
@@ -202,7 +202,7 @@ func TestLimitOneAfterDeletion(t *testing.T) {
 			Properties: map[string]interface{}{
 				"author": "Simon",
 			},
-		}, []float32{0, 1}, nil, "")
+		}, []float32{0, 1}, nil)
 
 		require.Nil(t, err)
 	})
@@ -221,7 +221,7 @@ func TestLimitOneAfterDeletion(t *testing.T) {
 			Properties: map[string]interface{}{
 				"author": "Simon",
 			},
-		}, []float32{0, 1}, nil, "")
+		}, []float32{0, 1}, nil)
 
 		require.Nil(t, err)
 	})
diff --git a/adapters/repos/db/filters_integration_test.go b/adapters/repos/db/filters_integration_test.go
index d590f2f8a0..722215ce87 100644
--- a/adapters/repos/db/filters_integration_test.go
+++ b/adapters/repos/db/filters_integration_test.go
@@ -10,7 +10,6 @@
 //
 
 //go:build integrationTest
-// +build integrationTest
 
 package db
 
@@ -104,7 +103,7 @@ func prepareCarTestSchemaAndData(repo *DB,
 		for i, fixture := range cars {
 			t.Run(fmt.Sprintf("importing car %d", i), func(t *testing.T) {
 				require.Nil(t,
-					repo.PutObject(context.Background(), &fixture, carVectors[i], nil, ""))
+					repo.PutObject(context.Background(), &fixture, carVectors[i], nil))
 			})
 		}
 	}
@@ -923,7 +922,7 @@ func TestGeoPropUpdateJourney(t *testing.T) {
 							Longitude: &coordinates[i][1],
 						},
 					},
-				}, []float32{0.5}, nil, "")
+				}, []float32{0.5}, nil)
 			}
 		}
 	}
@@ -1064,7 +1063,7 @@ func TestCasingOfOperatorCombinations(t *testing.T) {
 		for i, obj := range objects {
 			t.Run(fmt.Sprintf("importing object %d", i), func(t *testing.T) {
 				require.Nil(t,
-					repo.PutObject(context.Background(), obj, obj.Vector, nil, ""))
+					repo.PutObject(context.Background(), obj, obj.Vector, nil))
 			})
 		}
 	})
@@ -1432,7 +1431,7 @@ func TestFilteringAfterDeletion(t *testing.T) {
 		for i, obj := range objects {
 			t.Run(fmt.Sprintf("importing object %d", i), func(t *testing.T) {
 				require.Nil(t,
-					repo.PutObject(context.Background(), obj, obj.Vector, nil, ""))
+					repo.PutObject(context.Background(), obj, obj.Vector, nil))
 			})
 		}
 	})
diff --git a/adapters/repos/db/filters_limits_integration_test.go b/adapters/repos/db/filters_limits_integration_test.go
index ce9bc54728..21afb94fb6 100644
--- a/adapters/repos/db/filters_limits_integration_test.go
+++ b/adapters/repos/db/filters_limits_integration_test.go
@@ -76,7 +76,7 @@ func Test_LimitsOnChainedFilters(t *testing.T) {
 		for i, company := range data {
 			t.Run(fmt.Sprintf("importing product %d", i), func(t *testing.T) {
 				require.Nil(t,
-					repo.PutObject(context.Background(), company, []float32{0.1, 0.2, 0.01, 0.2}, nil, ""))
+					repo.PutObject(context.Background(), company, []float32{0.1, 0.2, 0.01, 0.2}, nil))
 			})
 		}
 	})
@@ -172,7 +172,7 @@ func Test_FilterLimitsAfterUpdates(t *testing.T) {
 		for i, company := range data {
 			t.Run(fmt.Sprintf("importing product %d", i), func(t *testing.T) {
 				require.Nil(t,
-					repo.PutObject(context.Background(), company, []float32{0.1, 0.2, 0.01, 0.2}, nil, ""))
+					repo.PutObject(context.Background(), company, []float32{0.1, 0.2, 0.01, 0.2}, nil))
 			})
 		}
 	})
@@ -214,7 +214,7 @@ func Test_FilterLimitsAfterUpdates(t *testing.T) {
 		for i, company := range data {
 			t.Run(fmt.Sprintf("importing product %d", i), func(t *testing.T) {
 				require.Nil(t,
-					repo.PutObject(context.Background(), company, []float32{0.1, 0.21, 0.01, 0.2}, nil, ""))
+					repo.PutObject(context.Background(), company, []float32{0.1, 0.21, 0.01, 0.2}, nil))
 			})
 		}
 	})
@@ -297,7 +297,7 @@ func Test_AggregationsAfterUpdates(t *testing.T) {
 		for i, company := range data {
 			t.Run(fmt.Sprintf("importing product %d", i), func(t *testing.T) {
 				require.Nil(t,
-					repo.PutObject(context.Background(), company, []float32{0.1, 0.2, 0.01, 0.2}, nil, ""))
+					repo.PutObject(context.Background(), company, []float32{0.1, 0.2, 0.01, 0.2}, nil))
 			})
 		}
 	})
@@ -324,7 +324,7 @@ func Test_AggregationsAfterUpdates(t *testing.T) {
 		for i, company := range data {
 			t.Run(fmt.Sprintf("importing product %d", i), func(t *testing.T) {
 				require.Nil(t,
-					repo.PutObject(context.Background(), company, []float32{0.1, 0.21, 0.01, 0.2}, nil, ""))
+					repo.PutObject(context.Background(), company, []float32{0.1, 0.21, 0.01, 0.2}, nil))
 			})
 		}
 	})
diff --git a/adapters/repos/db/filters_on_refs_integration_test.go b/adapters/repos/db/filters_on_refs_integration_test.go
index 0e79eed59e..f6c51b4b5d 100644
--- a/adapters/repos/db/filters_on_refs_integration_test.go
+++ b/adapters/repos/db/filters_on_refs_integration_test.go
@@ -195,7 +195,7 @@ func TestRefFilters(t *testing.T) {
 
 		for _, thing := range objects {
 			t.Run(fmt.Sprintf("add %s", thing.ID), func(t *testing.T) {
-				err := repo.PutObject(context.Background(), &thing, []float32{1, 2, 3, 4, 5, 6, 7}, nil, "")
+				err := repo.PutObject(context.Background(), &thing, []float32{1, 2, 3, 4, 5, 6, 7}, nil)
 				require.Nil(t, err)
 			})
 		}
@@ -643,7 +643,7 @@ func TestRefFilters_MergingWithAndOperator(t *testing.T) {
 		}
 
 		for _, obj := range objects {
-			require.Nil(t, repo.PutObject(context.Background(), obj, []float32{0.1}, nil, ""))
+			require.Nil(t, repo.PutObject(context.Background(), obj, []float32{0.1}, nil))
 		}
 	})
 
diff --git a/adapters/repos/db/index_integration_test.go b/adapters/repos/db/index_integration_test.go
index 0f85d43cb2..a8974f9143 100644
--- a/adapters/repos/db/index_integration_test.go
+++ b/adapters/repos/db/index_integration_test.go
@@ -139,7 +139,7 @@ func TestIndex_DropWithDataAndRecreateWithDataIndex(t *testing.T) {
 		}
 
 		err := index.putObject(context.TODO(), storobj.FromObject(
-			&product, []float32{0.1, 0.2, 0.01, 0.2}), nil, "")
+			&product, []float32{0.1, 0.2, 0.01, 0.2}), nil)
 		require.Nil(t, err)
 	}
 
@@ -201,7 +201,7 @@ func TestIndex_DropWithDataAndRecreateWithDataIndex(t *testing.T) {
 		}
 
 		err := index.putObject(context.TODO(), storobj.FromObject(
-			&thing, []float32{0.1, 0.2, 0.01, 0.2}), nil, "")
+			&thing, []float32{0.1, 0.2, 0.01, 0.2}), nil)
 		require.Nil(t, err)
 	}
 
@@ -298,7 +298,7 @@ func TestIndex_DropReadOnlyIndexWithData(t *testing.T) {
 		}
 
 		err := index.putObject(ctx, storobj.FromObject(
-			&product, []float32{0.1, 0.2, 0.01, 0.2}), nil, "")
+			&product, []float32{0.1, 0.2, 0.01, 0.2}), nil)
 		require.Nil(t, err)
 	}
 
diff --git a/adapters/repos/db/inverted_index_integration_test.go b/adapters/repos/db/inverted_index_integration_test.go
index 0753a8b6c3..7783fbe647 100644
--- a/adapters/repos/db/inverted_index_integration_test.go
+++ b/adapters/repos/db/inverted_index_integration_test.go
@@ -149,7 +149,7 @@ func TestIndexByTimestampsNullStatePropLength_AddClass(t *testing.T) {
 			Properties: map[string]interface{}{"initialWithIINil": "0", "initialWithIITrue": "0", "initialWithoutII": "1", "updateWithIINil": "2", "updateWithIITrue": "2", "updateWithoutII": "3"},
 		}
 		vec := []float32{1, 2, 3}
-		require.Nil(t, repo.PutObject(context.Background(), objWithProperty, vec, nil, ""))
+		require.Nil(t, repo.PutObject(context.Background(), objWithProperty, vec, nil))
 
 		testID2 := strfmt.UUID("a0b55b05-bc5b-4cc9-b646-1452d1390a63")
 		objWithoutProperty := &models.Object{
@@ -157,7 +157,7 @@ func TestIndexByTimestampsNullStatePropLength_AddClass(t *testing.T) {
 			Class:      "TestClass",
 			Properties: map[string]interface{}{},
 		}
-		require.Nil(t, repo.PutObject(context.Background(), objWithoutProperty, vec, nil, ""))
+		require.Nil(t, repo.PutObject(context.Background(), objWithoutProperty, vec, nil))
 
 		testID3 := strfmt.UUID("a0b55b05-bc5b-4cc9-b646-1452d1390a64")
 		objWithNilProperty := &models.Object{
@@ -165,7 +165,7 @@ func TestIndexByTimestampsNullStatePropLength_AddClass(t *testing.T) {
 			Class:      "TestClass",
 			Properties: map[string]interface{}{"initialWithIINil": nil, "initialWithIITrue": nil, "initialWithoutII": nil, "updateWithIINil": nil, "updateWithIITrue": nil, "updateWithoutII": nil},
 		}
-		require.Nil(t, repo.PutObject(context.Background(), objWithNilProperty, vec, nil, ""))
+		require.Nil(t, repo.PutObject(context.Background(), objWithNilProperty, vec, nil))
 	})
 
 	t.Run("delete class", func(t *testing.T) {
@@ -296,7 +296,7 @@ func TestIndexNullState_GetClass(t *testing.T) {
 				},
 			},
 		} {
-			err := repo.PutObject(context.Background(), obj, vec, nil, "")
+			err := repo.PutObject(context.Background(), obj, vec, nil)
 			require.Nil(t, err)
 		}
 	})
@@ -563,7 +563,7 @@ func TestIndexPropLength_GetClass(t *testing.T) {
 				},
 			},
 		} {
-			err := repo.PutObject(context.Background(), obj, vec, nil, "")
+			err := repo.PutObject(context.Background(), obj, vec, nil)
 			require.Nil(t, err)
 		}
 	})
@@ -911,7 +911,7 @@ func TestIndexByTimestamps_GetClass(t *testing.T) {
 				},
 			},
 		} {
-			err := repo.PutObject(context.Background(), obj, vec, nil, "")
+			err := repo.PutObject(context.Background(), obj, vec, nil)
 			require.Nil(t, err)
 		}
 	})
diff --git a/adapters/repos/db/merge_integration_test.go b/adapters/repos/db/merge_integration_test.go
index 97ba5c1a4b..8f45a33093 100644
--- a/adapters/repos/db/merge_integration_test.go
+++ b/adapters/repos/db/merge_integration_test.go
@@ -147,7 +147,7 @@ func Test_MergingObjects(t *testing.T) {
 			},
 			CreationTimeUnix:   now,
 			LastUpdateTimeUnix: now,
-		}, []float32{0.5}, nil, "")
+		}, []float32{0.5}, nil)
 		require.Nil(t, err)
 
 		targetDimensionsBefore := GetDimensionsFromRepo(repo, "MergeTestTarget")
@@ -161,7 +161,7 @@ func Test_MergingObjects(t *testing.T) {
 				Properties: map[string]interface{}{
 					"name": fmt.Sprintf("target item %d", i),
 				},
-			}, []float32{0.5}, nil, "")
+			}, []float32{0.5}, nil)
 			require.Nil(t, err)
 		}
 
@@ -176,7 +176,7 @@ func Test_MergingObjects(t *testing.T) {
 			},
 			CreationTimeUnix:   now,
 			LastUpdateTimeUnix: now,
-		}, nil, nil, "")
+		}, nil, nil)
 		require.Nil(t, err)
 
 		targetDimensionsAfterNoVec := GetDimensionsFromRepo(repo, "MergeTestTarget")
@@ -530,7 +530,7 @@ func Test_Merge_UntouchedPropsCorrectlyIndexed(t *testing.T) {
 			},
 			CreationTimeUnix:   int64(id),
 			LastUpdateTimeUnix: int64(id),
-		}, []float32{0.5}, nil, "")
+		}, []float32{0.5}, nil)
 		require.Nil(t, err)
 	})
 
diff --git a/adapters/repos/db/multi_shard_integration_test.go b/adapters/repos/db/multi_shard_integration_test.go
index f6d0db7464..13871da0da 100644
--- a/adapters/repos/db/multi_shard_integration_test.go
+++ b/adapters/repos/db/multi_shard_integration_test.go
@@ -58,7 +58,7 @@ func Test_MultiShardJourneys_IndividualImports(t *testing.T) {
 
 	t.Run("import all individually", func(t *testing.T) {
 		for _, obj := range data {
-			require.Nil(t, repo.PutObject(context.Background(), obj, obj.Vector, nil, ""))
+			require.Nil(t, repo.PutObject(context.Background(), obj, obj.Vector, nil))
 		}
 	})
 
@@ -71,7 +71,7 @@ func Test_MultiShardJourneys_IndividualImports(t *testing.T) {
 
 	t.Run("import refs individually", func(t *testing.T) {
 		for _, obj := range refData {
-			require.Nil(t, repo.PutObject(context.Background(), obj, obj.Vector, nil, ""))
+			require.Nil(t, repo.PutObject(context.Background(), obj, obj.Vector, nil))
 		}
 	})
 
@@ -105,7 +105,7 @@ func Test_MultiShardJourneys_BatchedImports(t *testing.T) {
 			}
 		}
 
-		_, err := repo.BatchPutObjects(context.Background(), batch, nil, "")
+		_, err := repo.BatchPutObjects(context.Background(), batch, nil)
 		require.Nil(t, err)
 	})
 
@@ -126,7 +126,7 @@ func Test_MultiShardJourneys_BatchedImports(t *testing.T) {
 				Properties: map[string]interface{}{}, // empty so we remove the ref
 			}
 
-			require.Nil(t, repo.PutObject(context.Background(), withoutRef, withoutRef.Vector, nil, ""))
+			require.Nil(t, repo.PutObject(context.Background(), withoutRef, withoutRef.Vector, nil))
 		}
 
 		index := 0
@@ -143,7 +143,7 @@ func Test_MultiShardJourneys_BatchedImports(t *testing.T) {
 			}
 		}
 
-		_, err := repo.AddBatchReferences(context.Background(), refBatch, nil, "")
+		_, err := repo.AddBatchReferences(context.Background(), refBatch, nil)
 		require.Nil(t, err)
 	})
 
@@ -232,7 +232,7 @@ func Test_MultiShardJourneys_BM25_Search(t *testing.T) {
 			},
 		}
 
-		_, err := repo.BatchPutObjects(context.Background(), objs, nil, "")
+		_, err := repo.BatchPutObjects(context.Background(), objs, nil)
 		require.Nil(t, err)
 	})
 
diff --git a/adapters/repos/db/nodes_integration_test.go b/adapters/repos/db/nodes_integration_test.go
index 418ea49b30..6a25ac237d 100644
--- a/adapters/repos/db/nodes_integration_test.go
+++ b/adapters/repos/db/nodes_integration_test.go
@@ -110,7 +110,7 @@ func TestNodesAPI_Journey(t *testing.T) {
 			UUID: "86a380e9-cb60-4b2a-bc48-51f52acd72d6",
 		},
 	}
-	batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil, "")
+	batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil)
 	require.Nil(t, err)
 
 	assert.Nil(t, batchRes[0].Err)
diff --git a/adapters/repos/db/ranked_fusion_test.go b/adapters/repos/db/ranked_fusion_test.go
index f3a075f7d9..3ac41d93fa 100644
--- a/adapters/repos/db/ranked_fusion_test.go
+++ b/adapters/repos/db/ranked_fusion_test.go
@@ -89,7 +89,7 @@ func SetupStandardTestData(t require.TestingT, repo *DB, schemaGetter *fakeSchem
 
 		data := map[string]interface{}{"document": doc.Document, "code": doc.DocID}
 		obj := &models.Object{Class: "StandardTest", ID: id, Properties: data, CreationTimeUnix: 1565612833955, LastUpdateTimeUnix: 10000020}
-		err := repo.PutObject(context.Background(), obj, nil, nil, "")
+		err := repo.PutObject(context.Background(), obj, nil, nil)
 		require.Nil(t, err)
 	}
 }
@@ -182,7 +182,7 @@ func addObj(repo *DB, i int, props map[string]interface{}, vec []float32) error
 
 	obj := &models.Object{Class: "MyClass", ID: id, Properties: props, CreationTimeUnix: 1565612833955, LastUpdateTimeUnix: 10000020}
 	vector := vec
-	err := repo.PutObject(context.Background(), obj, vector, nil, "")
+	err := repo.PutObject(context.Background(), obj, vector, nil)
 	return err
 }
 
diff --git a/adapters/repos/db/restart_journey_integration_test.go b/adapters/repos/db/restart_journey_integration_test.go
index 3e44e9f2b3..bf831bb9a5 100644
--- a/adapters/repos/db/restart_journey_integration_test.go
+++ b/adapters/repos/db/restart_journey_integration_test.go
@@ -78,7 +78,7 @@ func TestRestartJourney(t *testing.T) {
 			Properties: map[string]interface{}{
 				"description": "the band is just fantastic that is really what I think",
 			},
-		}, []float32{0.1, 0.2, 0.3}, nil, "")
+		}, []float32{0.1, 0.2, 0.3}, nil)
 		require.Nil(t, err)
 
 		err = repo.PutObject(context.Background(), &models.Object{
@@ -87,7 +87,7 @@ func TestRestartJourney(t *testing.T) {
 			Properties: map[string]interface{}{
 				"description": "oh by the way, which one's pink?",
 			},
-		}, []float32{-0.1, 0.2, -0.3}, nil, "")
+		}, []float32{-0.1, 0.2, -0.3}, nil)
 		require.Nil(t, err)
 	})
 
diff --git a/adapters/repos/db/shard_dimension_tracking_test.go b/adapters/repos/db/shard_dimension_tracking_test.go
index 42f8e00668..3046ae55a6 100644
--- a/adapters/repos/db/shard_dimension_tracking_test.go
+++ b/adapters/repos/db/shard_dimension_tracking_test.go
@@ -79,7 +79,7 @@ func Benchmark_Migration(b *testing.B) {
 
 				id := strfmt.UUID(uuid.MustParse(fmt.Sprintf("%032d", i)).String())
 				obj := &models.Object{Class: "Test", ID: id}
-				err := repo.PutObject(context.Background(), obj, vec, nil, "")
+				err := repo.PutObject(context.Background(), obj, vec, nil)
 				if err != nil {
 					b.Fatal(err)
 				}
@@ -145,7 +145,7 @@ func Test_Migration(t *testing.T) {
 
 			id := strfmt.UUID(uuid.MustParse(fmt.Sprintf("%032d", i)).String())
 			obj := &models.Object{Class: "Test", ID: id}
-			err := repo.PutObject(context.Background(), obj, vec, nil, "")
+			err := repo.PutObject(context.Background(), obj, vec, nil)
 			require.Nil(t, err)
 		}
 		dimAfter := GetDimensionsFromRepo(repo, "Test")
@@ -208,7 +208,7 @@ func Test_DimensionTracking(t *testing.T) {
 
 			id := strfmt.UUID(uuid.MustParse(fmt.Sprintf("%032d", i)).String())
 			obj := &models.Object{Class: "Test", ID: id}
-			err := repo.PutObject(context.Background(), obj, vec, nil, "")
+			err := repo.PutObject(context.Background(), obj, vec, nil)
 			require.Nil(t, err)
 		}
 		dimAfter := GetDimensionsFromRepo(repo, "Test")
@@ -220,7 +220,7 @@ func Test_DimensionTracking(t *testing.T) {
 		for i := 100; i < 200; i++ {
 			id := strfmt.UUID(uuid.MustParse(fmt.Sprintf("%032d", i)).String())
 			obj := &models.Object{Class: "Test", ID: id}
-			err := repo.PutObject(context.Background(), obj, nil, nil, "")
+			err := repo.PutObject(context.Background(), obj, nil, nil)
 			require.Nil(t, err)
 		}
 		dimAfter := GetDimensionsFromRepo(repo, "Test")
@@ -267,7 +267,7 @@ func Test_DimensionTracking(t *testing.T) {
 			obj := &models.Object{Class: "Test", ID: id}
 			// Put is idempotent, but since the IDs exist now, this is an update
 			// under the hood and a "reinstert" for the already deleted ones
-			err := repo.PutObject(context.Background(), obj, vec, nil, "")
+			err := repo.PutObject(context.Background(), obj, vec, nil)
 			require.Nil(t, err)
 		}
 		dimAfter := GetDimensionsFromRepo(repo, "Test")
@@ -281,7 +281,7 @@ func Test_DimensionTracking(t *testing.T) {
 			obj := &models.Object{Class: "Test", ID: id}
 			// Put is idempotent, but since the IDs exist now, this is an update
 			// under the hood and a "reinsert" for the already deleted ones
-			err := repo.PutObject(context.Background(), obj, nil, nil, "")
+			err := repo.PutObject(context.Background(), obj, nil, nil)
 			require.Nil(t, err)
 		}
 		dimAfter := GetDimensionsFromRepo(repo, "Test")
@@ -309,7 +309,7 @@ func Test_DimensionTracking(t *testing.T) {
 			obj := &models.Object{Class: "Test", ID: id}
 			// Put is idempotent, but since the IDs exist now, this is an update
 			// under the hood and a "reinsert" for the already deleted ones
-			err := repo.PutObject(context.Background(), obj, vec, nil, "")
+			err := repo.PutObject(context.Background(), obj, vec, nil)
 			require.Nil(t, err)
 		}
 		dimAfter := GetDimensionsFromRepo(repo, "Test")
@@ -323,7 +323,7 @@ func Test_DimensionTracking(t *testing.T) {
 			obj := &models.Object{Class: "Test", ID: id}
 			// Put is idempotent, but since the IDs exist now, this is an update
 			// under the hood and a "reinstert" for the already deleted ones
-			err := repo.PutObject(context.Background(), obj, nil, nil, "")
+			err := repo.PutObject(context.Background(), obj, nil, nil)
 			require.Nil(t, err)
 		}
 		dimAfter := GetDimensionsFromRepo(repo, "Test")
diff --git a/modules/text2vec-contextionary/classification/fakes_for_test.go b/modules/text2vec-contextionary/classification/fakes_for_test.go
index 38fc576ef7..64bac9215d 100644
--- a/modules/text2vec-contextionary/classification/fakes_for_test.go
+++ b/modules/text2vec-contextionary/classification/fakes_for_test.go
@@ -187,7 +187,7 @@ func (f *fakeVectorRepoKNN) VectorSearch(ctx context.Context,
 	return nil, fmt.Errorf("vector class search not implemented in fake")
 }
 
-func (f *fakeVectorRepoKNN) BatchPutObjects(ctx context.Context, objects objects.BatchObjects, repl *additional.ReplicationProperties, tenantKey string) (objects.BatchObjects, error) {
+func (f *fakeVectorRepoKNN) BatchPutObjects(ctx context.Context, objects objects.BatchObjects, repl *additional.ReplicationProperties) (objects.BatchObjects, error) {
 	f.Lock()
 	defer f.Unlock()
 
@@ -260,7 +260,7 @@ func (f *fakeVectorRepoContextual) ZeroShotSearch(ctx context.Context, vector []
 	panic("not implemented")
 }
 
-func (f *fakeVectorRepoContextual) BatchPutObjects(ctx context.Context, objects objects.BatchObjects, repl *additional.ReplicationProperties, tenantKey string) (objects.BatchObjects, error) {
+func (f *fakeVectorRepoContextual) BatchPutObjects(ctx context.Context, objects objects.BatchObjects, repl *additional.ReplicationProperties) (objects.BatchObjects, error) {
 	f.Lock()
 	defer f.Unlock()
 	for _, batchObject := range objects {
diff --git a/test/acceptance/multi_tenancy/add_tenant_objects_test.go b/test/acceptance/multi_tenancy/add_tenant_objects_test.go
index 9e554919e3..bd41f21e9f 100644
--- a/test/acceptance/multi_tenancy/add_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/add_tenant_objects_test.go
@@ -12,13 +12,12 @@
 package test
 
 import (
-	"fmt"
-	"net/http"
 	"testing"
 
+	"github.com/weaviate/weaviate/client/objects"
+
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-	"github.com/weaviate/weaviate/client/objects"
 	"github.com/weaviate/weaviate/entities/models"
 	"github.com/weaviate/weaviate/test/helper"
 )
@@ -29,8 +28,7 @@ func TestAddTenantObjects(t *testing.T) {
 	testClass := models.Class{
 		Class: className,
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -49,6 +47,7 @@ func TestAddTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[0],
 			},
+			TenantName: tenantNames[0],
 		},
 		{
 			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
@@ -56,6 +55,7 @@ func TestAddTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[1],
 			},
+			TenantName: tenantNames[1],
 		},
 		{
 			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
@@ -63,6 +63,7 @@ func TestAddTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[2],
 			},
+			TenantName: tenantNames[2],
 		},
 	}
 
@@ -83,8 +84,8 @@ func TestAddTenantObjects(t *testing.T) {
 	})
 
 	t.Run("add tenant objects", func(t *testing.T) {
-		for i, obj := range tenantObjects {
-			helper.CreateTenantObject(t, obj, tenantNames[i])
+		for _, obj := range tenantObjects {
+			helper.CreateObject(t, obj)
 		}
 	})
 
@@ -98,55 +99,68 @@ func TestAddTenantObjects(t *testing.T) {
 	})
 }
 
-func TestAddTenantObjects_MissingTenantKey(t *testing.T) {
-	className := "MultiTenantClass"
-	tenantKey := "tenantName"
-	tenantName := "Tenant1"
+func TestAddTenantObjectsToNonMultiClass(t *testing.T) {
+	className := "NoTenantClass"
+	tenantName := "randomTenant"
+	defer func() {
+		helper.DeleteClass(t, className)
+	}()
+
 	testClass := models.Class{
-		Class: className,
-		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
-		},
-		Properties: []*models.Property{
-			{
-				Name:     tenantKey,
-				DataType: []string{"string"},
-			},
-		},
+		Class:              className,
+		MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: false},
+	}
+	helper.CreateClass(t, &testClass)
+
+	objWithTenant := &models.Object{
+		ID:         "0927a1e0-398e-4e76-91fb-04a7a8f0405c",
+		Class:      className,
+		TenantName: tenantName,
+	}
+	params := objects.NewObjectsCreateParams().WithBody(objWithTenant)
+	_, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
+	require.NotNil(t, err)
+}
+
+func TestAddNonTenantObjectsToMultiClass(t *testing.T) {
+	className := "TenantClassFail"
+	defer func() {
+		helper.DeleteClass(t, className)
+	}()
+
+	testClass := models.Class{
+		Class:              className,
+		MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true},
 	}
-	tenantObject := models.Object{
+	helper.CreateClass(t, &testClass)
+	objWithTenant := &models.Object{
 		ID:    "0927a1e0-398e-4e76-91fb-04a7a8f0405c",
 		Class: className,
 	}
+	params := objects.NewObjectsCreateParams().WithBody(objWithTenant)
+	_, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
+	require.NotNil(t, err)
+}
 
+func TestAddObjectWithNonexistentTenantToMultiClass(t *testing.T) {
+	className := "TenantClass"
 	defer func() {
 		helper.DeleteClass(t, className)
 	}()
 
-	t.Run("create class with multi-tenancy enabled", func(t *testing.T) {
-		helper.CreateClass(t, &testClass)
-	})
-
-	t.Run("create tenants", func(t *testing.T) {
-		helper.CreateTenants(t, className, []*models.Tenant{{tenantName}})
-	})
+	testClass := models.Class{
+		Class:              className,
+		MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true},
+	}
+	helper.CreateClass(t, &testClass)
+	helper.CreateTenants(t, className, []*models.Tenant{{"randomTenant1"}})
 
-	t.Run("add tenant object", func(t *testing.T) {
-		params := objects.NewObjectsCreateParams().
-			WithBody(&tenantObject).WithTenantKey(&tenantName)
-		resp, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
-		require.Nil(t, resp)
-		require.NotNil(t, err)
-		parsedErr, ok := err.(*objects.ObjectsCreateUnprocessableEntity)
-		require.True(t, ok)
-		expected := "put object: import into index multitenantclass: " +
-			"tenant_key query param value \"Tenant1\" conflicts with object " +
-			"body value \"\" for class \"MultiTenantClass\" tenant key \"tenantName\""
-		require.NotNil(t, parsedErr.Payload)
-		require.NotNil(t, parsedErr.Payload.Error)
-		require.Len(t, parsedErr.Payload.Error, 1)
-		assert.Contains(t, err.Error(), fmt.Sprint(http.StatusUnprocessableEntity))
-		assert.Equal(t, expected, parsedErr.Payload.Error[0].Message)
-	})
+	objWithTenant := &models.Object{
+		ID:         "0927a1e0-398e-4e76-91fb-04a7a8f0405c",
+		Class:      className,
+		TenantName: "randomTenant2",
+	}
+	params := objects.NewObjectsCreateParams().WithBody(objWithTenant)
+	_, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
+	require.NotNil(t, err)
 }
diff --git a/test/acceptance/multi_tenancy/batch_add_tenant_objects_test.go b/test/acceptance/multi_tenancy/batch_add_tenant_objects_test.go
index cc038c8c50..a347d875d1 100644
--- a/test/acceptance/multi_tenancy/batch_add_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/batch_add_tenant_objects_test.go
@@ -12,9 +12,13 @@
 package test
 
 import (
-	"fmt"
 	"testing"
 
+	"github.com/go-openapi/strfmt"
+	"github.com/google/uuid"
+
+	"github.com/weaviate/weaviate/client/batch"
+
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"github.com/weaviate/weaviate/entities/models"
@@ -26,8 +30,7 @@ func TestBatchAddTenantObjects(t *testing.T) {
 	testClass := models.Class{
 		Class: "MultiTenantClass",
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -44,6 +47,7 @@ func TestBatchAddTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantName,
 			},
+			TenantName: tenantName,
 		},
 		{
 			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
@@ -51,6 +55,7 @@ func TestBatchAddTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantName,
 			},
+			TenantName: tenantName,
 		},
 		{
 			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
@@ -58,181 +63,202 @@ func TestBatchAddTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantName,
 			},
+			TenantName: tenantName,
 		},
 	}
 
+	helper.CreateClass(t, &testClass)
 	defer func() {
 		helper.DeleteClass(t, testClass.Class)
 	}()
 
-	t.Run("create class with multi-tenancy enabled", func(t *testing.T) {
-		helper.CreateClass(t, &testClass)
-	})
+	tenants := make([]*models.Tenant, len(tenantObjects))
+	for i := range tenants {
+		tenants[i] = &models.Tenant{tenantName}
+	}
+	helper.CreateTenants(t, testClass.Class, tenants)
 
-	t.Run("create tenants", func(t *testing.T) {
-		tenants := make([]*models.Tenant, len(tenantObjects))
-		for i := range tenants {
-			tenants[i] = &models.Tenant{tenantName}
-		}
-		helper.CreateTenants(t, testClass.Class, tenants)
-	})
+	t.Run("add and get tenant objects", func(t *testing.T) {
+		helper.CreateObjectsBatch(t, tenantObjects)
 
-	t.Run("add tenant objects", func(t *testing.T) {
-		resp, err := helper.CreateTenantObjectsBatch(t, tenantObjects, tenantName)
-		require.Nil(t, err)
-		helper.CheckObjectsBatchResponse(t, resp, err)
-	})
-
-	t.Run("get tenant objects", func(t *testing.T) {
 		for _, obj := range tenantObjects {
 			resp, err := helper.TenantObject(t, obj.Class, obj.ID, tenantName)
 			require.Nil(t, err)
 			assert.Equal(t, obj.ID, resp.ID)
 			assert.Equal(t, obj.Class, resp.Class)
 			assert.Equal(t, obj.Properties, resp.Properties)
+			assert.Equal(t, obj.TenantName, resp.Properties.(map[string]interface{})[tenantKey])
 		}
 	})
 }
 
-func TestBatchAddTenantObjects_MixedTenants(t *testing.T) {
-	tenantKey := "tenantName"
-	testClass := models.Class{
-		Class: "MultiTenantClass",
-		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
-		},
-		Properties: []*models.Property{
-			{
-				Name:     tenantKey,
-				DataType: []string{"string"},
+func TestBatchWithMixedTenants(t *testing.T) {
+	className := "MultiTenantClassMixedBatchFail"
+	classes := []models.Class{
+		{
+			Class: className + "1",
+			MultiTenancyConfig: &models.MultiTenancyConfig{
+				Enabled: true,
+			},
+		}, {
+			Class: className + "2",
+			MultiTenancyConfig: &models.MultiTenancyConfig{
+				Enabled: true,
 			},
 		},
 	}
-	tenantNames := []string{
-		"Tenant1", "Tenant2", "Tenant3",
+	tenants := []string{"tenant1", "tenant2", "tenant3"}
+	for i := range classes {
+		helper.CreateClass(t, &classes[i])
+		for k := range tenants {
+			helper.CreateTenants(t, classes[i].Class, []*models.Tenant{{tenants[k]}})
+		}
 	}
-	tenantObjects := []*models.Object{
+	defer func() {
+		for i := range classes {
+			helper.DeleteClass(t, classes[i].Class)
+		}
+	}()
+
+	var tenantObjects []*models.Object
+
+	for i := 0; i < 9; i++ {
+		tenantObjects = append(tenantObjects, &models.Object{
+			ID:         strfmt.UUID(uuid.New().String()),
+			Class:      classes[i%2].Class,
+			TenantName: tenants[i%len(tenants)],
+		},
+		)
+	}
+	helper.CreateObjectsBatch(t, tenantObjects)
+
+	for _, obj := range tenantObjects {
+		resp, err := helper.TenantObject(t, obj.Class, obj.ID, obj.TenantName)
+		require.Nil(t, err)
+		assert.Equal(t, obj.ID, resp.ID)
+		assert.Equal(t, obj.Class, resp.Class)
+	}
+}
+
+func TestAddNonTenantBatchToMultiClass(t *testing.T) {
+	className := "MultiTenantClassBatchFail"
+	testClass := models.Class{
+		Class: className,
+		MultiTenancyConfig: &models.MultiTenancyConfig{
+			Enabled: true,
+		},
+	}
+	nonTenantObjects := []*models.Object{
 		{
 			ID:    "0927a1e0-398e-4e76-91fb-04a7a8f0405c",
 			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantNames[0],
-			},
 		},
 		{
 			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
 			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantNames[1],
-			},
 		},
 		{
 			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
 			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantNames[2],
-			},
 		},
 	}
 
+	helper.CreateClass(t, &testClass)
 	defer func() {
 		helper.DeleteClass(t, testClass.Class)
 	}()
-
-	t.Run("create class with multi-tenancy enabled", func(t *testing.T) {
-		helper.CreateClass(t, &testClass)
-	})
-
-	t.Run("create tenants", func(t *testing.T) {
-		tenants := make([]*models.Tenant, len(tenantNames))
-		for i := range tenants {
-			tenants[i] = &models.Tenant{tenantNames[i]}
-		}
-		helper.CreateTenants(t, testClass.Class, tenants)
-	})
-
-	t.Run("add tenant objects", func(t *testing.T) {
-		otherTenant := "SomeOtherKey"
-		resp, err := helper.CreateTenantObjectsBatch(t, tenantObjects, otherTenant)
-		require.Nil(t, err)
-		for _, obj := range resp {
-			require.NotNil(t, obj.Result)
-			require.NotNil(t, obj.Result.Errors)
-			require.NotNil(t, obj.Result.Errors)
-			require.Len(t, obj.Result.Errors.Error, 1)
-			assert.Contains(t, obj.Result.Errors.Error[0].Message,
-				fmt.Sprintf("object does not belong to tenant %q", otherTenant))
-		}
-	})
+	helper.CreateTenants(t, className, []*models.Tenant{{"randomTenant1"}})
+	params := batch.NewBatchObjectsCreateParams().
+		WithBody(batch.BatchObjectsCreateBody{
+			Objects: nonTenantObjects,
+		})
+	resp, err := helper.Client(t).Batch.BatchObjectsCreate(params, nil)
+	require.Nil(t, err)
+	for i := range resp.Payload {
+		require.NotNil(t, resp.Payload[i].Result.Errors)
+	}
 }
 
-func TestBatchAddTenantObjects_MissingTenantKey(t *testing.T) {
-	tenantKey := "tenantName"
+func TestAddBatchToNonMultiClass(t *testing.T) {
+	className := "MultiTenantClassBatchFail"
 	testClass := models.Class{
-		Class: "MultiTenantClass",
+		Class: className,
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
-		},
-		Properties: []*models.Property{
-			{
-				Name:     tenantKey,
-				DataType: []string{"string"},
-			},
+			Enabled: false,
 		},
 	}
-	tenantName := "Tenant1"
 	tenantObjects := []*models.Object{
 		{
-			ID:    "0927a1e0-398e-4e76-91fb-04a7a8f0405c",
-			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantName,
-			},
+			ID:         "0927a1e0-398e-4e76-91fb-04a7a8f0405c",
+			Class:      testClass.Class,
+			TenantName: "something",
 		},
 		{
-			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
-			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantName,
-			},
+			ID:         "831ae1d0-f441-44b1-bb2a-46548048e26f",
+			Class:      testClass.Class,
+			TenantName: "something",
 		},
 		{
-			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
-			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantName,
-			},
+			ID:         "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
+			Class:      testClass.Class,
+			TenantName: "something",
 		},
 	}
 
+	helper.CreateClass(t, &testClass)
 	defer func() {
 		helper.DeleteClass(t, testClass.Class)
 	}()
+	params := batch.NewBatchObjectsCreateParams().
+		WithBody(batch.BatchObjectsCreateBody{
+			Objects: tenantObjects,
+		})
+	resp, err := helper.Client(t).Batch.BatchObjectsCreate(params, nil)
+	require.Nil(t, err)
+	for i := range resp.Payload {
+		require.NotNil(t, resp.Payload[i].Result.Errors)
+	}
+}
 
-	t.Run("create class with multi-tenancy enabled", func(t *testing.T) {
-		helper.CreateClass(t, &testClass)
-	})
+func TestAddBatchWithNonExistentTenant(t *testing.T) {
+	className := "MultiTenantClassBatchFail"
+	testClass := models.Class{
+		Class: className,
+		MultiTenancyConfig: &models.MultiTenancyConfig{
+			Enabled: true,
+		},
+	}
+	nonTenantObjects := []*models.Object{
+		{
+			ID:         "0927a1e0-398e-4e76-91fb-04a7a8f0405c",
+			Class:      testClass.Class,
+			TenantName: "something",
+		},
+		{
+			ID:         "831ae1d0-f441-44b1-bb2a-46548048e26f",
+			Class:      testClass.Class,
+			TenantName: "something",
+		},
+		{
+			ID:         "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
+			Class:      testClass.Class,
+			TenantName: "something",
+		},
+	}
 
-	t.Run("create tenants", func(t *testing.T) {
-		tenants := make([]*models.Tenant, len(tenantObjects))
-		for i := range tenants {
-			tenants[i] = &models.Tenant{tenantName}
-		}
-		helper.CreateTenants(t, testClass.Class, tenants)
-	})
+	helper.CreateClass(t, &testClass)
+	defer func() {
+		helper.DeleteClass(t, testClass.Class)
+	}()
+	helper.CreateTenants(t, className, []*models.Tenant{{"somethingElse"}})
 
-	t.Run("add tenant objects", func(t *testing.T) {
-		resp, err := helper.CreateTenantObjectsBatch(t, tenantObjects, "")
-		require.Nil(t, err)
-		for _, obj := range resp {
-			require.NotNil(t, obj.Result)
-			require.NotNil(t, obj.Result.Errors)
-			require.NotNil(t, obj.Result.Errors)
-			require.Len(t, obj.Result.Errors.Error, 1)
-			assert.Contains(t, obj.Result.Errors.Error[0].Message,
-				`class "MultiTenantClass" has multi-tenancy enabled, tenant_key "tenantName" required`)
-		}
-	})
+	params := batch.NewBatchObjectsCreateParams().
+		WithBody(batch.BatchObjectsCreateBody{
+			Objects: nonTenantObjects,
+		})
+	resp, err := helper.Client(t).Batch.BatchObjectsCreate(params, nil)
+	require.Nil(t, err)
+	for i := range resp.Payload {
+		require.NotNil(t, resp.Payload[i].Result.Errors)
+	}
 }
diff --git a/test/acceptance/multi_tenancy/batch_add_tenant_references_test.go b/test/acceptance/multi_tenancy/batch_add_tenant_references_test.go
index 1b43ecaade..1b118df97a 100644
--- a/test/acceptance/multi_tenancy/batch_add_tenant_references_test.go
+++ b/test/acceptance/multi_tenancy/batch_add_tenant_references_test.go
@@ -15,6 +15,8 @@ import (
 	"fmt"
 	"testing"
 
+	"github.com/google/uuid"
+
 	"github.com/go-openapi/strfmt"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
@@ -36,11 +38,8 @@ func TestBatchAddTenantReferences(t *testing.T) {
 	mtRefProp2 := "relatedToMT2"
 	stRefProp := "relatedToST"
 	mtClass1 := models.Class{
-		Class: className1,
-		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
-		},
+		Class:              className1,
+		MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true},
 		Properties: []*models.Property{
 			{
 				Name:     tenantKey,
@@ -63,8 +62,7 @@ func TestBatchAddTenantReferences(t *testing.T) {
 	mtClass2 := models.Class{
 		Class: className2,
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -97,6 +95,7 @@ func TestBatchAddTenantReferences(t *testing.T) {
 		Properties: map[string]interface{}{
 			tenantKey: tenantName1,
 		},
+		TenantName: tenantName1,
 	}
 	mtObject2DiffTenant := &models.Object{
 		ID:    "af90a7e3-53b3-4eb0-b395-10a04d217263",
@@ -104,6 +103,7 @@ func TestBatchAddTenantReferences(t *testing.T) {
 		Properties: map[string]interface{}{
 			tenantKey: tenantName2,
 		},
+		TenantName: tenantName2,
 	}
 	mtObject2SameTenant := &models.Object{
 		ID:    "4076df6b-0767-43a9-a0a4-2ec153bf262e",
@@ -111,6 +111,7 @@ func TestBatchAddTenantReferences(t *testing.T) {
 		Properties: map[string]interface{}{
 			tenantKey: tenantName1,
 		},
+		TenantName: tenantName1,
 	}
 	stObject1 := &models.Object{
 		ID:    "bea841c7-d689-4526-8af3-56c44b44274a",
@@ -145,9 +146,9 @@ func TestBatchAddTenantReferences(t *testing.T) {
 	})
 
 	t.Run("add tenant objects", func(t *testing.T) {
-		helper.CreateTenantObject(t, mtObject1, tenantName1)
-		helper.CreateTenantObject(t, mtObject2DiffTenant, tenantName2)
-		helper.CreateTenantObject(t, mtObject2SameTenant, tenantName1)
+		helper.CreateObject(t, mtObject1)
+		helper.CreateObject(t, mtObject2DiffTenant)
+		helper.CreateObject(t, mtObject2SameTenant)
 		helper.CreateObject(t, stObject1)
 		helper.CreateObject(t, stObject2)
 
@@ -182,10 +183,11 @@ func TestBatchAddTenantReferences(t *testing.T) {
 			{
 				From: strfmt.URI(crossref.NewSource(schema.ClassName(className1),
 					schema.PropertyName(mtRefProp1), mtObject1.ID).String()),
-				To: strfmt.URI(crossref.NewLocalhost(className1, mtObject1.ID).String()),
+				To:         strfmt.URI(crossref.NewLocalhost(className1, mtObject1.ID).String()),
+				TenantName: tenantName1,
 			},
 		}
-		resp, err := helper.AddTenantReferences(t, refs, tenantName1)
+		resp, err := helper.AddReferences(t, refs)
 		helper.CheckReferencesBatchResponse(t, resp, err)
 
 		t.Run("verify object references", func(t *testing.T) {
@@ -205,10 +207,11 @@ func TestBatchAddTenantReferences(t *testing.T) {
 			{
 				From: strfmt.URI(crossref.NewSource(schema.ClassName(className1),
 					schema.PropertyName(mtRefProp2), mtObject1.ID).String()),
-				To: strfmt.URI(crossref.NewLocalhost(className2, mtObject2SameTenant.ID).String()),
+				To:         strfmt.URI(crossref.NewLocalhost(className2, mtObject2SameTenant.ID).String()),
+				TenantName: tenantName1,
 			},
 		}
-		resp, err := helper.AddTenantReferences(t, refs, tenantName1)
+		resp, err := helper.AddReferences(t, refs)
 		helper.CheckReferencesBatchResponse(t, resp, err)
 
 		t.Run("verify object references", func(t *testing.T) {
@@ -223,16 +226,17 @@ func TestBatchAddTenantReferences(t *testing.T) {
 		})
 	})
 
-	t.Run("add tenant reference - different MT class and tenant", func(t *testing.T) {
+	t.Run("no references between different tenants", func(t *testing.T) {
 		refs := []*models.BatchReference{
 			{
 				From: strfmt.URI(crossref.NewSource(schema.ClassName(className1),
 					schema.PropertyName(mtRefProp2), mtObject1.ID).String()),
-				To: strfmt.URI(crossref.NewLocalhost(className2, mtObject2DiffTenant.ID).String()),
+				To:         strfmt.URI(crossref.NewLocalhost(className2, mtObject2DiffTenant.ID).String()),
+				TenantName: tenantName1,
 			},
 		}
 
-		resp, err := helper.AddTenantReferences(t, refs, tenantName1)
+		resp, err := helper.AddReferences(t, refs)
 		require.Nil(t, err)
 		require.NotNil(t, resp)
 		require.Len(t, resp, 1)
@@ -252,10 +256,11 @@ func TestBatchAddTenantReferences(t *testing.T) {
 			{
 				From: strfmt.URI(crossref.NewSource(schema.ClassName(className1),
 					schema.PropertyName(stRefProp), mtObject1.ID).String()),
-				To: strfmt.URI(crossref.NewLocalhost(className3, stObject1.ID).String()),
+				To:         strfmt.URI(crossref.NewLocalhost(className3, stObject1.ID).String()),
+				TenantName: tenantName1,
 			},
 		}
-		resp, err := helper.AddTenantReferences(t, refs, tenantName1)
+		resp, err := helper.AddReferences(t, refs)
 		helper.CheckReferencesBatchResponse(t, resp, err)
 
 		t.Run("verify object references", func(t *testing.T) {
@@ -270,7 +275,7 @@ func TestBatchAddTenantReferences(t *testing.T) {
 		})
 	})
 
-	t.Run("add tenant reference - from single tenant class to MT class", func(t *testing.T) {
+	t.Run("no references from single tenant class to MT class", func(t *testing.T) {
 		refs := []*models.BatchReference{
 			{
 				From: strfmt.URI(crossref.NewSource(schema.ClassName(className4),
@@ -293,3 +298,114 @@ func TestBatchAddTenantReferences(t *testing.T) {
 		assert.Equal(t, expectedMsg, resp[0].Result.Errors.Error[0].Message)
 	})
 }
+
+func TestAddMultipleTenantsForBatch(t *testing.T) {
+	tenants := []string{"tenant1", "tenant2"}
+	classNames := []string{"MultiTenantRefs1", "MultiTenantRefs2", "MultiTenantRefs3"}
+	refProps := []string{"refPropMT1", "refPropMT2", "refPropST1"}
+	classes := []models.Class{
+		{Class: classNames[0]},
+		{
+			Class:              classNames[1],
+			MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true},
+		},
+		{
+			Class:              classNames[2],
+			MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true},
+			Properties: []*models.Property{
+				{
+					Name:     refProps[0],
+					DataType: []string{classNames[0]},
+				},
+				{
+					Name:     refProps[1],
+					DataType: []string{classNames[1]},
+				},
+				{
+					Name:     refProps[2],
+					DataType: []string{classNames[2]},
+				},
+			},
+		},
+	}
+	defer func() {
+		for i := range classes {
+			helper.DeleteClass(t, classes[i].Class)
+		}
+	}()
+	for i := range classes {
+		helper.CreateClass(t, &classes[i])
+	}
+
+	for _, class := range classes[1:] {
+		for k := range tenants {
+			helper.CreateTenants(t, class.Class, []*models.Tenant{{tenants[k]}})
+		}
+	}
+
+	var tenantObjects []*models.Object
+	objMap := make(map[string][]int)
+
+	for i := 0; i < 9; i++ {
+		obj := &models.Object{
+			ID:    strfmt.UUID(uuid.New().String()),
+			Class: classes[i%len(classes)].Class,
+		}
+		if i%len(classes) > 0 { // only for MMT class
+			obj.TenantName = tenants[i%len(tenants)]
+		}
+		tenantObjects = append(tenantObjects, obj)
+		objMap[obj.Class] = append(objMap[obj.Class], i)
+	}
+	helper.CreateObjectsBatch(t, tenantObjects)
+
+	t.Run("refs between same class", func(t *testing.T) {
+		var refs []*models.BatchReference
+		for _, objectIndex := range objMap[classNames[2]] {
+			refs = append(refs, &models.BatchReference{
+				From: strfmt.URI(crossref.NewSource(schema.ClassName(classNames[2]),
+					schema.PropertyName(refProps[0]), tenantObjects[objectIndex].ID).String()),
+				To:         strfmt.URI(crossref.NewLocalhost(classNames[2], tenantObjects[objectIndex].ID).String()),
+				TenantName: tenantObjects[objectIndex].TenantName,
+			},
+			)
+		}
+		resp, err := helper.AddReferences(t, refs)
+		helper.CheckReferencesBatchResponse(t, resp, err)
+	})
+
+	t.Run("refs between multiple classes class", func(t *testing.T) {
+		var refs []*models.BatchReference
+		for _, objectIndexClass2 := range objMap[classNames[2]] {
+			objClass2 := tenantObjects[objectIndexClass2]
+			// refs between two MMT classes
+			for _, objectIndexClass1 := range objMap[classNames[1]] {
+				objClass1 := tenantObjects[objectIndexClass1]
+
+				if objClass2.TenantName != objClass1.TenantName {
+					continue
+				}
+
+				refs = append(refs, &models.BatchReference{
+					From: strfmt.URI(crossref.NewSource(schema.ClassName(classNames[2]),
+						schema.PropertyName(refProps[0]), objClass2.ID).String()),
+					To:         strfmt.URI(crossref.NewLocalhost(classNames[1], objClass1.ID).String()),
+					TenantName: objClass1.TenantName,
+				})
+			}
+
+			// refs between MMT and non MMT class
+			for _, objectIndexClass0 := range objMap[classNames[0]] {
+				objClass0 := tenantObjects[objectIndexClass0]
+				refs = append(refs, &models.BatchReference{
+					From: strfmt.URI(crossref.NewSource(schema.ClassName(classNames[2]),
+						schema.PropertyName(refProps[0]), objClass2.ID).String()),
+					To:         strfmt.URI(crossref.NewLocalhost(classNames[0], objClass0.ID).String()),
+					TenantName: objClass2.TenantName,
+				})
+			}
+		}
+		resp, err := helper.AddReferences(t, refs)
+		helper.CheckReferencesBatchResponse(t, resp, err)
+	})
+}
diff --git a/test/acceptance/multi_tenancy/batch_delete_tenant_objects_test.go b/test/acceptance/multi_tenancy/batch_delete_tenant_objects_test.go
index 38edc808f0..5a2f4d743f 100644
--- a/test/acceptance/multi_tenancy/batch_delete_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/batch_delete_tenant_objects_test.go
@@ -16,7 +16,6 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
-	"github.com/weaviate/weaviate/client/batch"
 	"github.com/weaviate/weaviate/client/objects"
 	"github.com/weaviate/weaviate/entities/filters"
 	"github.com/weaviate/weaviate/entities/models"
@@ -29,8 +28,7 @@ func TestBatchDeleteTenantObjects(t *testing.T) {
 	testClass := models.Class{
 		Class: className,
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -47,6 +45,7 @@ func TestBatchDeleteTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantName,
 			},
+			TenantName: tenantName,
 		},
 		{
 			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
@@ -54,6 +53,7 @@ func TestBatchDeleteTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantName,
 			},
+			TenantName: tenantName,
 		},
 		{
 			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
@@ -61,6 +61,7 @@ func TestBatchDeleteTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantName,
 			},
+			TenantName: tenantName,
 		},
 	}
 
@@ -81,9 +82,7 @@ func TestBatchDeleteTenantObjects(t *testing.T) {
 	})
 
 	t.Run("add tenant objects", func(t *testing.T) {
-		resp, err := helper.CreateTenantObjectsBatch(t, tenantObjects, tenantName)
-		require.Nil(t, err)
-		helper.CheckObjectsBatchResponse(t, resp, err)
+		helper.CreateObjectsBatch(t, tenantObjects)
 
 		t.Run("verify tenant objects", func(t *testing.T) {
 			for _, obj := range tenantObjects {
@@ -126,101 +125,3 @@ func TestBatchDeleteTenantObjects(t *testing.T) {
 		})
 	})
 }
-
-func TestBatchDeleteTenantObjects_MissingTenantKey(t *testing.T) {
-	className := "MultiTenantClass"
-	tenantKey := "tenantName"
-	testClass := models.Class{
-		Class: className,
-		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
-		},
-		Properties: []*models.Property{
-			{
-				Name:     tenantKey,
-				DataType: []string{"string"},
-			},
-		},
-	}
-	tenantName := "Tenant1"
-	tenantObjects := []*models.Object{
-		{
-			ID:    "0927a1e0-398e-4e76-91fb-04a7a8f0405c",
-			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantName,
-			},
-		},
-		{
-			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
-			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantName,
-			},
-		},
-		{
-			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
-			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantName,
-			},
-		},
-	}
-
-	defer func() {
-		helper.DeleteClass(t, className)
-	}()
-
-	t.Run("create class with multi-tenancy enabled", func(t *testing.T) {
-		helper.CreateClass(t, &testClass)
-	})
-
-	t.Run("create tenants", func(t *testing.T) {
-		tenants := make([]*models.Tenant, len(tenantObjects))
-		for i := range tenants {
-			tenants[i] = &models.Tenant{tenantName}
-		}
-		helper.CreateTenants(t, className, tenants)
-	})
-
-	t.Run("add tenant objects", func(t *testing.T) {
-		resp, err := helper.CreateTenantObjectsBatch(t, tenantObjects, tenantName)
-		require.Nil(t, err)
-		helper.CheckObjectsBatchResponse(t, resp, err)
-
-		t.Run("verify tenant objects", func(t *testing.T) {
-			for _, obj := range tenantObjects {
-				resp, err := helper.TenantObject(t, obj.Class, obj.ID, tenantName)
-				require.Nil(t, err)
-				require.Equal(t, obj.ID, resp.ID)
-				require.Equal(t, obj.Class, resp.Class)
-				require.Equal(t, obj.Properties, resp.Properties)
-			}
-		})
-	})
-
-	t.Run("batch delete tenant objects", func(t *testing.T) {
-		glob := "*"
-		where := models.WhereFilter{
-			Operator:    filters.OperatorLike.Name(),
-			Path:        []string{"id"},
-			ValueString: &glob,
-		}
-		match := models.BatchDeleteMatch{
-			Class: className,
-			Where: &where,
-		}
-		params := batch.NewBatchObjectsDeleteParams().WithBody(&models.BatchDelete{Match: &match})
-		resp, err := helper.Client(t).Batch.BatchObjectsDelete(params, nil)
-		badReqErr, ok := err.(*batch.BatchObjectsDeleteUnprocessableEntity)
-		require.Nil(t, resp)
-		require.NotNil(t, err)
-		require.True(t, ok, "expected *batch.BatchObjectsDeleteUnprocessableEntity, got: %T", err)
-		require.NotNil(t, badReqErr.Payload)
-		require.NotNil(t, badReqErr.Payload.Error)
-		require.Len(t, badReqErr.Payload.Error, 1)
-		assert.Contains(t, badReqErr.Payload.Error[0].Message,
-			`class "MultiTenantClass" has multi-tenancy enabled, tenant_key "tenantName" required`)
-	})
-}
diff --git a/test/acceptance/multi_tenancy/create_tenants_test.go b/test/acceptance/multi_tenancy/create_tenants_test.go
index 9d11b872fc..077af83cc5 100644
--- a/test/acceptance/multi_tenancy/create_tenants_test.go
+++ b/test/acceptance/multi_tenancy/create_tenants_test.go
@@ -26,8 +26,7 @@ func TestCreateTenants(t *testing.T) {
 	testClass := models.Class{
 		Class: "MultiTenantClass",
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
diff --git a/test/acceptance/multi_tenancy/delete_tenant_objects_test.go b/test/acceptance/multi_tenancy/delete_tenant_objects_test.go
index b2263c8903..062b716e8a 100644
--- a/test/acceptance/multi_tenancy/delete_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/delete_tenant_objects_test.go
@@ -26,8 +26,7 @@ func TestDeleteTenantObjects(t *testing.T) {
 	testClass := models.Class{
 		Class: "MultiTenantClass",
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -46,6 +45,7 @@ func TestDeleteTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[0],
 			},
+			TenantName: tenantNames[0],
 		},
 		{
 			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
@@ -53,6 +53,7 @@ func TestDeleteTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[1],
 			},
+			TenantName: tenantNames[1],
 		},
 		{
 			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
@@ -60,6 +61,7 @@ func TestDeleteTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[2],
 			},
+			TenantName: tenantNames[2],
 		},
 	}
 
@@ -80,8 +82,8 @@ func TestDeleteTenantObjects(t *testing.T) {
 	})
 
 	t.Run("add tenant objects", func(t *testing.T) {
-		for i, obj := range tenantObjects {
-			helper.CreateTenantObject(t, obj, tenantNames[i])
+		for _, obj := range tenantObjects {
+			helper.CreateObject(t, obj)
 		}
 
 		t.Run("verify tenant objects creation", func(t *testing.T) {
diff --git a/test/acceptance/multi_tenancy/get_tenant_objects_test.go b/test/acceptance/multi_tenancy/get_tenant_objects_test.go
index 6523a306d2..46a6a9adb7 100644
--- a/test/acceptance/multi_tenancy/get_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/get_tenant_objects_test.go
@@ -25,8 +25,7 @@ func TestGetTenantObjects(t *testing.T) {
 	testClass := models.Class{
 		Class: "MultiTenantClass",
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -45,6 +44,7 @@ func TestGetTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[0],
 			},
+			TenantName: tenantNames[0],
 		},
 		{
 			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
@@ -52,6 +52,7 @@ func TestGetTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[1],
 			},
+			TenantName: tenantNames[1],
 		},
 		{
 			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
@@ -59,6 +60,7 @@ func TestGetTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[2],
 			},
+			TenantName: tenantNames[2],
 		},
 	}
 
@@ -79,8 +81,8 @@ func TestGetTenantObjects(t *testing.T) {
 	})
 
 	t.Run("add tenant objects", func(t *testing.T) {
-		for i, obj := range tenantObjects {
-			helper.CreateTenantObject(t, obj, tenantNames[i])
+		for _, obj := range tenantObjects {
+			helper.CreateObject(t, obj)
 		}
 	})
 
diff --git a/test/acceptance/multi_tenancy/gql_aggregate_tenant_objects_test.go b/test/acceptance/multi_tenancy/gql_aggregate_tenant_objects_test.go
index 359a50aae0..5aee8317b8 100644
--- a/test/acceptance/multi_tenancy/gql_aggregate_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/gql_aggregate_tenant_objects_test.go
@@ -29,8 +29,7 @@ func TestGQLAggregateTenantObjects(t *testing.T) {
 	testClass := models.Class{
 		Class: "MultiTenantClass",
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -75,12 +74,8 @@ func TestGQLAggregateTenantObjects(t *testing.T) {
 				batchSize:  numTenantObjs2,
 			})
 
-			resp, err := helper.CreateTenantObjectsBatch(t, batch1, tenantName1)
-			require.Nil(t, err)
-			helper.CheckObjectsBatchResponse(t, resp, err)
-			resp, err = helper.CreateTenantObjectsBatch(t, batch2, tenantName2)
-			require.Nil(t, err)
-			helper.CheckObjectsBatchResponse(t, resp, err)
+			helper.CreateObjectsBatch(t, batch1)
+			helper.CreateObjectsBatch(t, batch2)
 		})
 	})
 
@@ -131,8 +126,7 @@ func TestGQLAggregateTenantObjects_InvalidTenantKey(t *testing.T) {
 	testClass := models.Class{
 		Class: "MultiTenantClass",
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -167,18 +161,10 @@ func TestGQLAggregateTenantObjects_InvalidTenantKey(t *testing.T) {
 				tenantKey:  tenantKey,
 				batchSize:  numTenantObjs,
 			})
-			resp, err := helper.CreateTenantObjectsBatch(t, batch, tenantName)
-			require.Nil(t, err)
-			helper.CheckObjectsBatchResponse(t, resp, err)
+			helper.CreateObjectsBatch(t, batch)
 		})
 	})
 
-	t.Run("missing tenant key", func(t *testing.T) {
-		query := fmt.Sprintf(`{Aggregate{%s{meta{count}}}}`, testClass.Class)
-		expected := `class "MultiTenantClass" has multi-tenancy enabled, tenant_key "tenantName" required`
-		testAggregateTenantFailure(t, testClass.Class, query, expected)
-	})
-
 	t.Run("non-existent tenant key", func(t *testing.T) {
 		query := fmt.Sprintf(`{Aggregate{%s(tenantKey:"DNE"){meta{count}}}}`, testClass.Class)
 		expected := `shard DNE: class MultiTenantClass has no physical shard "DNE"`
@@ -201,6 +187,7 @@ func makeTenantBatch(params batchParams) []*models.Object {
 			Properties: map[string]interface{}{
 				params.tenantKey: params.tenantName,
 			},
+			TenantName: params.tenantName,
 		}
 	}
 	return batch
diff --git a/test/acceptance/multi_tenancy/gql_get_tenant_objects_test.go b/test/acceptance/multi_tenancy/gql_get_tenant_objects_test.go
index fdaad6b88a..d762193ace 100644
--- a/test/acceptance/multi_tenancy/gql_get_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/gql_get_tenant_objects_test.go
@@ -13,7 +13,6 @@ package test
 
 import (
 	"fmt"
-	"strings"
 	"testing"
 
 	"github.com/go-openapi/strfmt"
@@ -29,8 +28,7 @@ func TestGQLGetTenantObjects(t *testing.T) {
 	testClass := models.Class{
 		Class: "MultiTenantClass",
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -47,6 +45,7 @@ func TestGQLGetTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantName,
 			},
+			TenantName: tenantName,
 		},
 		{
 			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
@@ -54,6 +53,7 @@ func TestGQLGetTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantName,
 			},
+			TenantName: tenantName,
 		},
 		{
 			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
@@ -61,6 +61,7 @@ func TestGQLGetTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantName,
 			},
+			TenantName: tenantName,
 		},
 	}
 
@@ -82,9 +83,7 @@ func TestGQLGetTenantObjects(t *testing.T) {
 		})
 
 		t.Run("add tenant objects", func(t *testing.T) {
-			resp, err := helper.CreateTenantObjectsBatch(t, tenantObjects, tenantName)
-			require.Nil(t, err)
-			helper.CheckObjectsBatchResponse(t, resp, err)
+			helper.CreateObjectsBatch(t, tenantObjects)
 		})
 
 		t.Run("get tenant objects", func(t *testing.T) {
@@ -122,91 +121,3 @@ func TestGQLGetTenantObjects(t *testing.T) {
 		}
 	})
 }
-
-func TestGQLGetTenantObjects_MissingTenantKey(t *testing.T) {
-	tenantKey := "tenantName"
-	testClass := models.Class{
-		Class: "MultiTenantClass",
-		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
-		},
-		Properties: []*models.Property{
-			{
-				Name:     tenantKey,
-				DataType: []string{"string"},
-			},
-		},
-	}
-	tenantName := "Tenant1"
-	tenantObjects := []*models.Object{
-		{
-			ID:    "0927a1e0-398e-4e76-91fb-04a7a8f0405c",
-			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantName,
-			},
-		},
-		{
-			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
-			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantName,
-			},
-		},
-		{
-			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
-			Class: testClass.Class,
-			Properties: map[string]interface{}{
-				tenantKey: tenantName,
-			},
-		},
-	}
-
-	defer func() {
-		helper.DeleteClass(t, testClass.Class)
-	}()
-
-	t.Run("setup test data", func(t *testing.T) {
-		t.Run("create class with multi-tenancy enabled", func(t *testing.T) {
-			helper.CreateClass(t, &testClass)
-		})
-
-		t.Run("create tenants", func(t *testing.T) {
-			tenants := make([]*models.Tenant, len(tenantObjects))
-			for i := range tenants {
-				tenants[i] = &models.Tenant{tenantName}
-			}
-			helper.CreateTenants(t, testClass.Class, tenants)
-		})
-
-		t.Run("add tenant objects", func(t *testing.T) {
-			resp, err := helper.CreateTenantObjectsBatch(t, tenantObjects, tenantName)
-			require.Nil(t, err)
-			helper.CheckObjectsBatchResponse(t, resp, err)
-		})
-
-		t.Run("get tenant objects", func(t *testing.T) {
-			for _, obj := range tenantObjects {
-				resp, err := helper.TenantObject(t, obj.Class, obj.ID, tenantName)
-				require.Nil(t, err)
-				assert.Equal(t, obj.ID, resp.ID)
-				assert.Equal(t, obj.Class, resp.Class)
-				assert.Equal(t, obj.Properties, resp.Properties)
-			}
-		})
-	})
-
-	t.Run("GQL Get tenant objects", func(t *testing.T) {
-		query := fmt.Sprintf(`{Get{%s{_additional{id}}}}`, testClass.Class)
-		result, err := graphqlhelper.QueryGraphQL(t, helper.RootAuth, "", query, nil)
-		require.Nil(t, err)
-		require.Len(t, result.Errors, 1)
-		assert.Nil(t, result.Data["Get"].(map[string]interface{})[testClass.Class])
-		msg := fmt.Sprintf(`explorer: list class: search: object search at index %s: `,
-			strings.ToLower(testClass.Class)) +
-			fmt.Sprintf(`class %q has multi-tenancy enabled, tenant_key %q required`,
-				testClass.Class, tenantKey)
-		assert.Equal(t, result.Errors[0].Message, msg)
-	})
-}
diff --git a/test/acceptance/multi_tenancy/head_tenant_objects_test.go b/test/acceptance/multi_tenancy/head_tenant_objects_test.go
index ddacac094a..d5a201b75c 100644
--- a/test/acceptance/multi_tenancy/head_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/head_tenant_objects_test.go
@@ -25,8 +25,7 @@ func TestHeadTenantObjects(t *testing.T) {
 	testClass := models.Class{
 		Class: "MultiTenantClass",
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -45,6 +44,7 @@ func TestHeadTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[0],
 			},
+			TenantName: tenantNames[0],
 		},
 		{
 			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
@@ -52,6 +52,7 @@ func TestHeadTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[1],
 			},
+			TenantName: tenantNames[1],
 		},
 		{
 			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
@@ -59,6 +60,7 @@ func TestHeadTenantObjects(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: tenantNames[2],
 			},
+			TenantName: tenantNames[2],
 		},
 	}
 
@@ -79,8 +81,8 @@ func TestHeadTenantObjects(t *testing.T) {
 	})
 
 	t.Run("add tenant objects", func(t *testing.T) {
-		for i, obj := range tenantObjects {
-			helper.CreateTenantObject(t, obj, tenantNames[i])
+		for _, obj := range tenantObjects {
+			helper.CreateObject(t, obj)
 		}
 	})
 
diff --git a/test/acceptance/multi_tenancy/patch_tenant_objects_test.go b/test/acceptance/multi_tenancy/patch_tenant_objects_test.go
index a6b8d9378e..987867707e 100644
--- a/test/acceptance/multi_tenancy/patch_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/patch_tenant_objects_test.go
@@ -29,8 +29,7 @@ func TestPatchTenantObjects(t *testing.T) {
 	testClass := models.Class{
 		Class: "MultiTenantClass",
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -53,6 +52,7 @@ func TestPatchTenantObjects(t *testing.T) {
 				tenantKey:   tenantNames[0],
 				mutableProp: "obj#0",
 			},
+			TenantName: tenantNames[0],
 		},
 		{
 			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
@@ -61,6 +61,7 @@ func TestPatchTenantObjects(t *testing.T) {
 				tenantKey:   tenantNames[1],
 				mutableProp: "obj#1",
 			},
+			TenantName: tenantNames[1],
 		},
 		{
 			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
@@ -69,6 +70,7 @@ func TestPatchTenantObjects(t *testing.T) {
 				tenantKey:   tenantNames[2],
 				mutableProp: "obj#2",
 			},
+			TenantName: tenantNames[2],
 		},
 	}
 
@@ -89,8 +91,8 @@ func TestPatchTenantObjects(t *testing.T) {
 	})
 
 	t.Run("add tenant objects", func(t *testing.T) {
-		for i, obj := range tenantObjects {
-			helper.CreateTenantObject(t, obj, tenantNames[i])
+		for _, obj := range tenantObjects {
+			helper.CreateObject(t, obj)
 		}
 
 		t.Run("verify tenant object creation", func(t *testing.T) {
@@ -114,8 +116,9 @@ func TestPatchTenantObjects(t *testing.T) {
 					tenantKey:   tenantNames[i],
 					mutableProp: fmt.Sprintf("%s--patched", mut),
 				},
+				TenantName: tenantNames[i],
 			}
-			helper.PatchTenantObject(t, toUpdate, tenantNames[i])
+			helper.PatchObject(t, toUpdate)
 		}
 
 		t.Run("assert tenant object updates", func(t *testing.T) {
@@ -133,14 +136,13 @@ func TestPatchTenantObjects(t *testing.T) {
 }
 
 func TestPatchTenantObjects_ChangeTenantKey(t *testing.T) {
-	className := "MultiTenantClass"
+	className := "MultiTenantClassPatch"
 	tenantKey := "tenantName"
 	tenantName := "Tenant1"
 	testClass := models.Class{
 		Class: className,
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -155,6 +157,7 @@ func TestPatchTenantObjects_ChangeTenantKey(t *testing.T) {
 		Properties: map[string]interface{}{
 			tenantKey: tenantName,
 		},
+		TenantName: tenantName,
 	}
 
 	defer func() {
@@ -168,7 +171,7 @@ func TestPatchTenantObjects_ChangeTenantKey(t *testing.T) {
 
 	t.Run("add tenant object", func(t *testing.T) {
 		params := objects.NewObjectsCreateParams().
-			WithBody(&tenantObject).WithTenantKey(&tenantName)
+			WithBody(&tenantObject)
 		_, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
 		require.Nil(t, err)
 	})
@@ -180,18 +183,18 @@ func TestPatchTenantObjects_ChangeTenantKey(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: "updatedTenantName",
 			},
+			TenantName: "updatedTenantName",
 		}
 		params := objects.NewObjectsClassPatchParams().WithClassName(toUpdate.Class).
-			WithID(toUpdate.ID).WithBody(&toUpdate).WithTenantKey(&tenantName)
-		resp, err := helper.Client(t).Objects.ObjectsClassPatch(params, nil)
-		require.Nil(t, resp)
-		require.NotNil(t, err)
-		parsedErr, ok := err.(*objects.ObjectsClassPatchUnprocessableEntity)
+			WithID(toUpdate.ID).WithBody(&toUpdate)
+		_, err := helper.Client(t).Objects.ObjectsClassPatch(params, nil)
+		require.NotNil(t, err) // tenant does not exist
+		parsedErr, ok := err.(*objects.ObjectsClassPatchInternalServerError)
 		require.True(t, ok)
 		require.NotNil(t, parsedErr.Payload.Error)
 		require.Len(t, parsedErr.Payload.Error, 1)
-		assert.Contains(t, err.Error(), fmt.Sprint(http.StatusUnprocessableEntity))
-		expected := "tenant key \"tenantName\" is immutable"
+		assert.Contains(t, err.Error(), fmt.Sprint(http.StatusInternalServerError))
+		expected := "no tenant found with key: \"updatedTenantName\""
 		assert.Contains(t, parsedErr.Payload.Error[0].Message, expected)
 	})
 }
diff --git a/test/acceptance/multi_tenancy/tenant_objects_reference_test.go b/test/acceptance/multi_tenancy/tenant_objects_reference_test.go
index 6aaeade3a3..b65db95ac3 100644
--- a/test/acceptance/multi_tenancy/tenant_objects_reference_test.go
+++ b/test/acceptance/multi_tenancy/tenant_objects_reference_test.go
@@ -28,8 +28,7 @@ func TestTenantObjectsReference(t *testing.T) {
 	testClass := models.Class{
 		Class: "MultiTenantClass",
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -57,6 +56,7 @@ func TestTenantObjectsReference(t *testing.T) {
 				tenantKey:   tenantNames[0],
 				mutableProp: "obj#0",
 			},
+			TenantName: tenantNames[0],
 		},
 		{
 			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
@@ -65,6 +65,7 @@ func TestTenantObjectsReference(t *testing.T) {
 				tenantKey:   tenantNames[1],
 				mutableProp: "obj#1",
 			},
+			TenantName: tenantNames[1],
 		},
 		{
 			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
@@ -73,6 +74,7 @@ func TestTenantObjectsReference(t *testing.T) {
 				tenantKey:   tenantNames[2],
 				mutableProp: "obj#2",
 			},
+			TenantName: tenantNames[2],
 		},
 	}
 	tenantRefs := []*models.Object{
@@ -83,6 +85,7 @@ func TestTenantObjectsReference(t *testing.T) {
 				tenantKey:   tenantNames[0],
 				mutableProp: "ref#0",
 			},
+			TenantName: tenantNames[0],
 		},
 		{
 			ID:    "4d78424d-f7bd-479b-bd8a-52510e2db0fd",
@@ -91,6 +94,7 @@ func TestTenantObjectsReference(t *testing.T) {
 				tenantKey:   tenantNames[1],
 				mutableProp: "ref#1",
 			},
+			TenantName: tenantNames[1],
 		},
 		{
 			ID:    "c1db0a06-d5f9-4f77-aa3c-08a44f16e358",
@@ -99,6 +103,7 @@ func TestTenantObjectsReference(t *testing.T) {
 				tenantKey:   tenantNames[2],
 				mutableProp: "ref#2",
 			},
+			TenantName: tenantNames[2],
 		},
 	}
 
@@ -120,8 +125,8 @@ func TestTenantObjectsReference(t *testing.T) {
 
 	t.Run("add tenant objects", func(t *testing.T) {
 		for i, obj := range tenantObjects {
-			helper.CreateTenantObject(t, obj, tenantNames[i])
-			helper.CreateTenantObject(t, tenantRefs[i], tenantNames[i])
+			helper.CreateObject(t, obj)
+			helper.CreateObject(t, tenantRefs[i])
 		}
 
 		t.Run("verify tenant object creation", func(t *testing.T) {
diff --git a/test/acceptance/multi_tenancy/update_tenant_objects_test.go b/test/acceptance/multi_tenancy/update_tenant_objects_test.go
index ff2f4a8094..3fb5b240b3 100644
--- a/test/acceptance/multi_tenancy/update_tenant_objects_test.go
+++ b/test/acceptance/multi_tenancy/update_tenant_objects_test.go
@@ -29,8 +29,7 @@ func TestUpdateTenantObjects(t *testing.T) {
 	testClass := models.Class{
 		Class: "MultiTenantClass",
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -53,6 +52,7 @@ func TestUpdateTenantObjects(t *testing.T) {
 				tenantKey:   tenantNames[0],
 				mutableProp: "obj#0",
 			},
+			TenantName: tenantNames[0],
 		},
 		{
 			ID:    "831ae1d0-f441-44b1-bb2a-46548048e26f",
@@ -61,6 +61,7 @@ func TestUpdateTenantObjects(t *testing.T) {
 				tenantKey:   tenantNames[1],
 				mutableProp: "obj#1",
 			},
+			TenantName: tenantNames[1],
 		},
 		{
 			ID:    "6f3363e0-c0a0-4618-bf1f-b6cad9cdff59",
@@ -69,6 +70,7 @@ func TestUpdateTenantObjects(t *testing.T) {
 				tenantKey:   tenantNames[2],
 				mutableProp: "obj#2",
 			},
+			TenantName: tenantNames[2],
 		},
 	}
 
@@ -89,8 +91,8 @@ func TestUpdateTenantObjects(t *testing.T) {
 	})
 
 	t.Run("add tenant objects", func(t *testing.T) {
-		for i, obj := range tenantObjects {
-			helper.CreateTenantObject(t, obj, tenantNames[i])
+		for _, obj := range tenantObjects {
+			helper.CreateObject(t, obj)
 		}
 
 		t.Run("verify tenant object creation", func(t *testing.T) {
@@ -114,8 +116,9 @@ func TestUpdateTenantObjects(t *testing.T) {
 					tenantKey:   tenantNames[i],
 					mutableProp: fmt.Sprintf("%s--updated", mut),
 				},
+				TenantName: tenantNames[i],
 			}
-			helper.UpdateTenantObject(t, toUpdate, tenantNames[i])
+			helper.UpdateObject(t, toUpdate)
 		}
 
 		t.Run("assert tenant object updates", func(t *testing.T) {
@@ -132,68 +135,6 @@ func TestUpdateTenantObjects(t *testing.T) {
 	})
 }
 
-func TestUpdateTenantObjects_MissingTenantKey(t *testing.T) {
-	className := "MultiTenantClass"
-	tenantKey := "tenantName"
-	tenantName := "Tenant1"
-	testClass := models.Class{
-		Class: className,
-		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
-		},
-		Properties: []*models.Property{
-			{
-				Name:     tenantKey,
-				DataType: []string{"string"},
-			},
-		},
-	}
-	tenantObject := models.Object{
-		ID:    "0927a1e0-398e-4e76-91fb-04a7a8f0405c",
-		Class: className,
-		Properties: map[string]interface{}{
-			tenantKey: tenantName,
-		},
-	}
-
-	defer func() {
-		helper.DeleteClass(t, className)
-	}()
-
-	t.Run("create class with multi-tenancy enabled", func(t *testing.T) {
-		helper.CreateClass(t, &testClass)
-		helper.CreateTenants(t, className, []*models.Tenant{{tenantName}})
-	})
-
-	t.Run("add tenant object", func(t *testing.T) {
-		params := objects.NewObjectsCreateParams().
-			WithBody(&tenantObject).WithTenantKey(&tenantName)
-		_, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
-		require.Nil(t, err)
-	})
-
-	t.Run("update tenant object", func(t *testing.T) {
-		toUpdate := models.Object{
-			Class: testClass.Class,
-			ID:    tenantObject.ID,
-		}
-		params := objects.NewObjectsClassPutParams().WithClassName(toUpdate.Class).
-			WithID(toUpdate.ID).WithBody(&toUpdate).WithTenantKey(&tenantName)
-		resp, err := helper.Client(t).Objects.ObjectsClassPut(params, nil)
-		require.Nil(t, resp)
-		require.NotNil(t, err)
-		parsedErr, ok := err.(*objects.ObjectsClassPutUnprocessableEntity)
-		require.True(t, ok)
-		require.NotNil(t, parsedErr.Payload.Error)
-		require.Len(t, parsedErr.Payload.Error, 1)
-		assert.Contains(t, err.Error(), fmt.Sprint(http.StatusUnprocessableEntity))
-		expected := "tenant_key query param value \"Tenant1\" conflicts with object " +
-			"body value \"\" for class \"MultiTenantClass\" tenant key \"tenantName\""
-		assert.Contains(t, parsedErr.Payload.Error[0].Message, expected)
-	})
-}
-
 func TestUpdateTenantObjects_UpdateTenantKey(t *testing.T) {
 	className := "MultiTenantClass"
 	tenantKey := "tenantName"
@@ -201,8 +142,7 @@ func TestUpdateTenantObjects_UpdateTenantKey(t *testing.T) {
 	testClass := models.Class{
 		Class: className,
 		MultiTenancyConfig: &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		},
 		Properties: []*models.Property{
 			{
@@ -217,6 +157,7 @@ func TestUpdateTenantObjects_UpdateTenantKey(t *testing.T) {
 		Properties: map[string]interface{}{
 			tenantKey: tenantName,
 		},
+		TenantName: tenantName,
 	}
 
 	defer func() {
@@ -230,7 +171,7 @@ func TestUpdateTenantObjects_UpdateTenantKey(t *testing.T) {
 
 	t.Run("add tenant object", func(t *testing.T) {
 		params := objects.NewObjectsCreateParams().
-			WithBody(&tenantObject).WithTenantKey(&tenantName)
+			WithBody(&tenantObject)
 		_, err := helper.Client(t).Objects.ObjectsCreate(params, nil)
 		require.Nil(t, err)
 	})
@@ -242,18 +183,18 @@ func TestUpdateTenantObjects_UpdateTenantKey(t *testing.T) {
 			Properties: map[string]interface{}{
 				tenantKey: "updatedTenantName",
 			},
+			TenantName: "updatedTenantName",
 		}
 		params := objects.NewObjectsClassPutParams().WithClassName(toUpdate.Class).
-			WithID(toUpdate.ID).WithBody(&toUpdate).WithTenantKey(&tenantName)
-		resp, err := helper.Client(t).Objects.ObjectsClassPut(params, nil)
-		require.Nil(t, resp)
-		require.NotNil(t, err)
-		parsedErr, ok := err.(*objects.ObjectsClassPutUnprocessableEntity)
+			WithID(toUpdate.ID).WithBody(&toUpdate)
+		_, err := helper.Client(t).Objects.ObjectsClassPut(params, nil)
+		require.NotNil(t, err) // tenant does not exist
+		parsedErr, ok := err.(*objects.ObjectsClassPutInternalServerError)
 		require.True(t, ok)
 		require.NotNil(t, parsedErr.Payload.Error)
 		require.Len(t, parsedErr.Payload.Error, 1)
-		assert.Contains(t, err.Error(), fmt.Sprint(http.StatusUnprocessableEntity))
-		expected := "tenant key \"tenantName\" is immutable"
+		assert.Contains(t, err.Error(), fmt.Sprint(http.StatusInternalServerError))
+		expected := "no tenant found with key: \"updatedTenantName\""
 		assert.Contains(t, parsedErr.Payload.Error[0].Message, expected)
 	})
 }
diff --git a/test/acceptance/replication/crud_ops.go b/test/acceptance/replication/crud_ops.go
index 1c6e5c77bf..835f4a0919 100644
--- a/test/acceptance/replication/crud_ops.go
+++ b/test/acceptance/replication/crud_ops.go
@@ -49,9 +49,9 @@ func createObjectCL(t *testing.T, host string, obj *models.Object, cl replica.Co
 	helper.CreateObjectCL(t, obj, cl)
 }
 
-func createTenantObject(t *testing.T, host string, obj *models.Object, tenantKey string) {
+func createTenantObject(t *testing.T, host string, obj *models.Object) {
 	helper.SetupClient(host)
-	helper.CreateTenantObject(t, obj, tenantKey)
+	helper.CreateObject(t, obj)
 }
 
 func createObjects(t *testing.T, host string, batch []*models.Object) {
@@ -59,9 +59,9 @@ func createObjects(t *testing.T, host string, batch []*models.Object) {
 	helper.CreateObjectsBatch(t, batch)
 }
 
-func createTenantObjects(t *testing.T, host string, batch []*models.Object, tenantKey string) {
+func createTenantObjects(t *testing.T, host string, batch []*models.Object) {
 	helper.SetupClient(host)
-	helper.CreateTenantObjectsBatch(t, batch, tenantKey)
+	helper.CreateObjectsBatch(t, batch)
 }
 
 func getObject(t *testing.T, host, class string, id strfmt.UUID) (*models.Object, error) {
@@ -99,9 +99,9 @@ func patchObject(t *testing.T, host string, patch *models.Object) {
 	helper.PatchObject(t, patch)
 }
 
-func patchTenantObject(t *testing.T, host string, patch *models.Object, tenantKey string) {
+func patchTenantObject(t *testing.T, host string, patch *models.Object) {
 	helper.SetupClient(host)
-	helper.PatchTenantObject(t, patch, tenantKey)
+	helper.PatchObject(t, patch)
 }
 
 func updateObjectCL(t *testing.T, host string, obj *models.Object, cl replica.ConsistencyLevel) {
@@ -115,9 +115,9 @@ func addReferences(t *testing.T, host string, refs []*models.BatchReference) {
 	helper.CheckReferencesBatchResponse(t, resp, err)
 }
 
-func addTenantReferences(t *testing.T, host string, refs []*models.BatchReference, tenantKey string) {
+func addTenantReferences(t *testing.T, host string, refs []*models.BatchReference) {
 	helper.SetupClient(host)
-	resp, err := helper.AddTenantReferences(t, refs, tenantKey)
+	resp, err := helper.AddReferences(t, refs)
 	helper.CheckReferencesBatchResponse(t, resp, err)
 }
 
diff --git a/test/acceptance/replication/multi_tenancy_test.go b/test/acceptance/replication/multi_tenancy_test.go
index d441d7021d..f00ed60724 100644
--- a/test/acceptance/replication/multi_tenancy_test.go
+++ b/test/acceptance/replication/multi_tenancy_test.go
@@ -59,16 +59,14 @@ func multiTenancyEnabled(t *testing.T) {
 			Factor: 2,
 		}
 		paragraphClass.MultiTenancyConfig = &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		}
 		helper.CreateClass(t, paragraphClass)
 		articleClass.ReplicationConfig = &models.ReplicationConfig{
 			Factor: 2,
 		}
 		articleClass.MultiTenancyConfig = &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: tenantKey,
+			Enabled: true,
 		}
 		helper.CreateClass(t, articleClass)
 	})
@@ -86,10 +84,10 @@ func multiTenancyEnabled(t *testing.T) {
 				batch[i] = articles.NewParagraph().
 					WithID(id).
 					WithContents(fmt.Sprintf("paragraph#%d", i)).
-					WithTenantKey(tenantID.String()).
+					WithTenant(tenantID.String()).
 					Object()
 			}
-			createTenantObjects(t, compose.GetWeaviate().URI(), batch, tenantID.String())
+			createTenantObjects(t, compose.GetWeaviate().URI(), batch)
 		})
 
 		t.Run("stop node 1", func(t *testing.T) {
@@ -113,9 +111,9 @@ func multiTenancyEnabled(t *testing.T) {
 				obj := articles.NewArticle().
 					WithID(id).
 					WithTitle(fmt.Sprintf("Article#%d", i)).
-					WithTenantKey(tenantID.String()).
+					WithTenant(tenantID.String()).
 					Object()
-				createTenantObject(t, compose.GetWeaviateNode2().URI(), obj, tenantID.String())
+				createTenantObject(t, compose.GetWeaviateNode2().URI(), obj)
 			}
 		})
 
@@ -139,13 +137,14 @@ func multiTenancyEnabled(t *testing.T) {
 		refs := make([]*models.BatchReference, len(articleIDs))
 		for i := range articleIDs {
 			refs[i] = &models.BatchReference{
-				From: strfmt.URI(crossref.NewSource("Article", "hasParagraphs", articleIDs[i]).String()),
-				To:   strfmt.URI(crossref.NewLocalhost("Paragraph", paragraphIDs[i]).String()),
+				From:       strfmt.URI(crossref.NewSource("Article", "hasParagraphs", articleIDs[i]).String()),
+				To:         strfmt.URI(crossref.NewLocalhost("Paragraph", paragraphIDs[i]).String()),
+				TenantName: tenantID.String(),
 			}
 		}
 
 		t.Run("add references to node 1", func(t *testing.T) {
-			addTenantReferences(t, compose.GetWeaviate().URI(), refs, tenantID.String())
+			addTenantReferences(t, compose.GetWeaviate().URI(), refs)
 		})
 
 		t.Run("stop node 1", func(t *testing.T) {
@@ -202,8 +201,9 @@ func multiTenancyEnabled(t *testing.T) {
 				ID:         before.ID,
 				Class:      "Article",
 				Properties: map[string]interface{}{"title": newTitle, tenantKey: tenantID.String()},
+				TenantName: tenantID.String(),
 			}
-			patchTenantObject(t, compose.GetWeaviateNode2().URI(), patch, tenantID.String())
+			patchTenantObject(t, compose.GetWeaviateNode2().URI(), patch)
 		})
 
 		t.Run("stop node 2", func(t *testing.T) {
diff --git a/test/helper/journey/backup_journey.go b/test/helper/journey/backup_journey.go
index 8d0c121b93..276644b77e 100644
--- a/test/helper/journey/backup_journey.go
+++ b/test/helper/journey/backup_journey.go
@@ -12,7 +12,6 @@
 package journey
 
 import (
-	"fmt"
 	"math/rand"
 	"testing"
 	"time"
@@ -35,7 +34,7 @@ const (
 
 const (
 	singleTenant = ""
-	multiTenant  = "tenantID"
+	multiTenant  = true
 )
 
 func backupJourney(t *testing.T, className, backend, backupID string,
@@ -138,7 +137,7 @@ func backupJourney(t *testing.T, className, backend, backupID string,
 	}
 }
 
-func addTestClass(t *testing.T, className string, tenantKey string) {
+func addTestClass(t *testing.T, className string, multiTenant bool) {
 	class := &models.Class{
 		Class: className,
 		ModuleConfig: map[string]interface{}{
@@ -155,21 +154,16 @@ func addTestClass(t *testing.T, className string, tenantKey string) {
 		},
 	}
 
-	if tenantKey != singleTenant {
-		class.Properties = append(class.Properties, &models.Property{
-			Name:     multiTenant,
-			DataType: []string{"string"},
-		})
+	if multiTenant {
 		class.MultiTenancyConfig = &models.MultiTenancyConfig{
-			Enabled:   true,
-			TenantKey: multiTenant,
+			Enabled: true,
 		}
 	}
 
 	helper.CreateClass(t, class)
 }
 
-func addTestObjects(t *testing.T, className string, tenantKey string) {
+func addTestObjects(t *testing.T, className string, tenantNames []string) {
 	const (
 		noteLengthMin = 4
 		noteLengthMax = 1024
@@ -179,6 +173,7 @@ func addTestObjects(t *testing.T, className string, tenantKey string) {
 	)
 
 	seededRand := rand.New(rand.NewSource(time.Now().UnixNano()))
+	multiTenant := len(tenantNames) > 0
 
 	for i := 0; i < numBatches; i++ {
 		batch := make([]*models.Object, batchSize)
@@ -190,17 +185,12 @@ func addTestObjects(t *testing.T, className string, tenantKey string) {
 				Class:      className,
 				Properties: map[string]interface{}{"contents": contents},
 			}
-			if tenantKey != singleTenant {
-				obj.Properties.(map[string]interface{})[multiTenant] = fmt.Sprintf("Tenant%d", i)
+			if multiTenant {
+				obj.TenantName = tenantNames[i]
 			}
 			batch[j] = &obj
 		}
+		helper.CreateObjectsBatch(t, batch)
 
-		if tenantKey != singleTenant {
-			resp, err := helper.CreateTenantObjectsBatch(t, batch, fmt.Sprintf("Tenant%d", i))
-			helper.CheckObjectsBatchResponse(t, resp, err)
-		} else {
-			helper.CreateObjectsBatch(t, batch)
-		}
 	}
 }
diff --git a/test/helper/journey/cluster_backup_journey.go b/test/helper/journey/cluster_backup_journey.go
index 4e276d93e1..77b91fe411 100644
--- a/test/helper/journey/cluster_backup_journey.go
+++ b/test/helper/journey/cluster_backup_journey.go
@@ -36,13 +36,13 @@ func clusterBackupJourneyTest(t *testing.T, backend, className, backupID,
 				tenants[i] = &models.Tenant{Name: tenantNames[i]}
 			}
 			helper.CreateTenants(t, className, tenants)
-			addTestObjects(t, className, multiTenant)
+			addTestObjects(t, className, tenantNames)
 		})
 	} else {
 		// upload data to a node other than the coordinator
 		t.Run(fmt.Sprintf("add test data to endpoint: %s", uploaderEndpoint), func(t *testing.T) {
-			addTestClass(t, className, singleTenant)
-			addTestObjects(t, className, singleTenant)
+			addTestClass(t, className, !multiTenant)
+			addTestObjects(t, className, nil)
 		})
 	}
 
diff --git a/test/helper/journey/single_node_backup_journey.go b/test/helper/journey/single_node_backup_journey.go
index bb64a72476..1870bfaa69 100644
--- a/test/helper/journey/single_node_backup_journey.go
+++ b/test/helper/journey/single_node_backup_journey.go
@@ -34,12 +34,12 @@ func singleNodeBackupJourneyTest(t *testing.T,
 				tenants[i] = &models.Tenant{Name: tenantNames[i]}
 			}
 			helper.CreateTenants(t, className, tenants)
-			addTestObjects(t, className, multiTenant)
+			addTestObjects(t, className, tenantNames)
 		})
 	} else {
 		t.Run("add test data", func(t *testing.T) {
-			addTestClass(t, className, singleTenant)
-			addTestObjects(t, className, singleTenant)
+			addTestClass(t, className, !multiTenant)
+			addTestObjects(t, className, nil)
 		})
 	}
 
diff --git a/test/helper/objects.go b/test/helper/objects.go
index 277dfe7319..74612da79a 100644
--- a/test/helper/objects.go
+++ b/test/helper/objects.go
@@ -69,12 +69,6 @@ func CreateObjectCL(t *testing.T, object *models.Object, cl replica.ConsistencyL
 	AssertRequestOk(t, resp, err, nil)
 }
 
-func CreateTenantObject(t *testing.T, object *models.Object, tenantKey string) {
-	params := objects.NewObjectsCreateParams().WithBody(object).WithTenantKey(&tenantKey)
-	resp, err := Client(t).Objects.ObjectsCreate(params, nil)
-	AssertRequestOk(t, resp, err, nil)
-}
-
 func CreateObjectsBatch(t *testing.T, objects []*models.Object) {
 	params := batch.NewBatchObjectsCreateParams().
 		WithBody(batch.BatchObjectsCreateBody{
@@ -95,18 +89,6 @@ func CheckObjectsBatchResponse(t *testing.T, resp []*models.ObjectsGetResponse,
 	}
 }
 
-func CreateTenantObjectsBatch(t *testing.T, objects []*models.Object,
-	tenantKey string,
-) ([]*models.ObjectsGetResponse, error) {
-	params := batch.NewBatchObjectsCreateParams().
-		WithBody(batch.BatchObjectsCreateBody{
-			Objects: objects,
-		}).WithTenantKey(&tenantKey)
-	resp, err := Client(t).Batch.BatchObjectsCreate(params, nil)
-	AssertRequestOk(t, resp, err, nil)
-	return resp.Payload, err
-}
-
 func UpdateObject(t *testing.T, object *models.Object) {
 	params := objects.NewObjectsUpdateParams().WithID(object.ID).WithBody(object)
 	resp, err := Client(t).Objects.ObjectsUpdate(params, nil)
@@ -121,26 +103,12 @@ func UpdateObjectCL(t *testing.T, object *models.Object, cl replica.ConsistencyL
 	AssertRequestOk(t, resp, err, nil)
 }
 
-func UpdateTenantObject(t *testing.T, object *models.Object, tenantKey string) {
-	params := objects.NewObjectsClassPutParams().WithClassName(object.Class).
-		WithID(object.ID).WithBody(object).WithTenantKey(&tenantKey)
-	resp, err := Client(t).Objects.ObjectsClassPut(params, nil)
-	AssertRequestOk(t, resp, err, nil)
-}
-
 func PatchObject(t *testing.T, object *models.Object) {
 	params := objects.NewObjectsPatchParams().WithID(object.ID).WithBody(object)
 	resp, err := Client(t).Objects.ObjectsPatch(params, nil)
 	AssertRequestOk(t, resp, err, nil)
 }
 
-func PatchTenantObject(t *testing.T, object *models.Object, tenantKey string) {
-	params := objects.NewObjectsClassPatchParams().WithClassName(object.Class).
-		WithID(object.ID).WithBody(object).WithTenantKey(&tenantKey)
-	resp, err := Client(t).Objects.ObjectsClassPatch(params, nil)
-	AssertRequestOk(t, resp, err, nil)
-}
-
 func DeleteClass(t *testing.T, class string) {
 	delParams := schema.NewSchemaObjectsDeleteParams().WithClassName(class)
 	delRes, err := Client(t).Schema.SchemaObjectsDelete(delParams, nil)
@@ -181,18 +149,6 @@ func AddReferences(t *testing.T, refs []*models.BatchReference) ([]*models.Batch
 	return resp.Payload, nil
 }
 
-func AddTenantReferences(t *testing.T, refs []*models.BatchReference,
-	tenantKey string,
-) ([]*models.BatchReferenceResponse, error) {
-	params := batch.NewBatchReferencesCreateParams().
-		WithBody(refs).WithTenantKey(&tenantKey)
-	resp, err := Client(t).Batch.BatchReferencesCreate(params, nil)
-	if err != nil {
-		return nil, err
-	}
-	return resp.Payload, nil
-}
-
 func CheckReferencesBatchResponse(t *testing.T, resp []*models.BatchReferenceResponse, err error) {
 	AssertRequestOk(t, resp, err, nil)
 	for _, elem := range resp {
diff --git a/test/helper/sample-schema/articles/articles.go b/test/helper/sample-schema/articles/articles.go
index f9ca90d997..3869353434 100644
--- a/test/helper/sample-schema/articles/articles.go
+++ b/test/helper/sample-schema/articles/articles.go
@@ -75,9 +75,8 @@ func (a *Article) WithTitle(title string) *Article {
 	return a
 }
 
-func (a *Article) WithTenantKey(tk string) *Article {
-	props := a.Properties.(map[string]interface{})
-	props["tenantKey"] = tk
+func (a *Article) WithTenant(tk string) *Article {
+	a.TenantName = tk
 	return a
 }
 
@@ -112,9 +111,8 @@ func (p *Paragraph) WithVector(vec []float32) *Paragraph {
 	return p
 }
 
-func (p *Paragraph) WithTenantKey(tk string) *Paragraph {
-	props := p.Properties.(map[string]interface{})
-	props["tenantKey"] = tk
+func (p *Paragraph) WithTenant(tk string) *Paragraph {
+	p.TenantName = tk
 	return p
 }
 
diff --git a/usecases/classification/fakes_for_test.go b/usecases/classification/fakes_for_test.go
index 6ac06d06c2..c92ad4449e 100644
--- a/usecases/classification/fakes_for_test.go
+++ b/usecases/classification/fakes_for_test.go
@@ -188,7 +188,7 @@ func (f *fakeVectorRepoKNN) VectorSearch(ctx context.Context,
 	return nil, fmt.Errorf("vector class search not implemented in fake")
 }
 
-func (f *fakeVectorRepoKNN) BatchPutObjects(ctx context.Context, objects objects.BatchObjects, repl *additional.ReplicationProperties, tenantKey string) (objects.BatchObjects, error) {
+func (f *fakeVectorRepoKNN) BatchPutObjects(ctx context.Context, objects objects.BatchObjects, repl *additional.ReplicationProperties) (objects.BatchObjects, error) {
 	f.Lock()
 	defer f.Unlock()
 
@@ -261,7 +261,7 @@ func (f *fakeVectorRepoContextual) ZeroShotSearch(ctx context.Context, vector []
 	panic("not implemented")
 }
 
-func (f *fakeVectorRepoContextual) BatchPutObjects(ctx context.Context, objects objects.BatchObjects, repl *additional.ReplicationProperties, tenantKey string) (objects.BatchObjects, error) {
+func (f *fakeVectorRepoContextual) BatchPutObjects(ctx context.Context, objects objects.BatchObjects, repl *additional.ReplicationProperties) (objects.BatchObjects, error) {
 	f.Lock()
 	defer f.Unlock()
 	for _, batchObject := range objects {
diff --git a/usecases/classification/integrationtest/classifier_integration_test.go b/usecases/classification/integrationtest/classifier_integration_test.go
index 2fea40c921..e59d5055b0 100644
--- a/usecases/classification/integrationtest/classifier_integration_test.go
+++ b/usecases/classification/integrationtest/classifier_integration_test.go
@@ -79,7 +79,7 @@ func Test_Classifier_KNN_SaveConsistency(t *testing.T) {
 				}
 			}
 
-			res, err := vrepo.BatchPutObjects(context.Background(), bt, nil, "")
+			res, err := vrepo.BatchPutObjects(context.Background(), bt, nil)
 			require.Nil(t, err)
 			for _, elem := range res {
 				require.Nil(t, elem.Err)
@@ -96,7 +96,7 @@ func Test_Classifier_KNN_SaveConsistency(t *testing.T) {
 					Object:        elem.Object(),
 				}
 			}
-			res, err := vrepo.BatchPutObjects(context.Background(), bt, nil, "")
+			res, err := vrepo.BatchPutObjects(context.Background(), bt, nil)
 			require.Nil(t, err)
 			for _, elem := range res {
 				require.Nil(t, elem.Err)
@@ -214,7 +214,7 @@ func Test_Classifier_ZeroShot_SaveConsistency(t *testing.T) {
 				}
 			}
 
-			res, err := vrepo.BatchPutObjects(context.Background(), bt, nil, "")
+			res, err := vrepo.BatchPutObjects(context.Background(), bt, nil)
 			require.Nil(t, err)
 			for _, elem := range res {
 				require.Nil(t, elem.Err)
diff --git a/usecases/objects/add_test.go b/usecases/objects/add_test.go
index 6a8c209372..04cab53b00 100644
--- a/usecases/objects/add_test.go
+++ b/usecases/objects/add_test.go
@@ -93,7 +93,7 @@ func Test_Add_Object_WithNoVectorizerModule(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 
-		res, err := manager.AddObject(ctx, nil, class, nil, "")
+		res, err := manager.AddObject(ctx, nil, class, nil)
 		require.Nil(t, err)
 		uuidDuringCreation := vectorRepo.Mock.Calls[0].Arguments.Get(0).(*models.Object).ID
 
@@ -115,7 +115,7 @@ func Test_Add_Object_WithNoVectorizerModule(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 
-		res, err := manager.AddObject(ctx, nil, object, nil, "")
+		res, err := manager.AddObject(ctx, nil, object, nil)
 		require.Nil(t, err)
 		uuidDuringCreation := vectorRepo.Mock.Calls[1].Arguments.Get(0).(*models.Object).ID
 
@@ -138,7 +138,7 @@ func Test_Add_Object_WithNoVectorizerModule(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 
-		res, err := manager.AddObject(ctx, nil, object, nil, "")
+		res, err := manager.AddObject(ctx, nil, object, nil)
 		require.Nil(t, err)
 		assert.Equal(t, res.ID, lowered, "check that id was lowered and added")
 	})
@@ -160,7 +160,7 @@ func Test_Add_Object_WithNoVectorizerModule(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 
-		res, err := manager.AddObject(ctx, nil, object, nil, "")
+		res, err := manager.AddObject(ctx, nil, object, nil)
 		require.Nil(t, err)
 		uuidDuringCreation := vectorRepo.Mock.Calls[1].Arguments.Get(0).(*models.Object).ID
 
@@ -182,7 +182,7 @@ func Test_Add_Object_WithNoVectorizerModule(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 
-		_, err := manager.AddObject(ctx, nil, class, nil, "")
+		_, err := manager.AddObject(ctx, nil, class, nil)
 		assert.Equal(t, NewErrInvalidUserInput("id '%s' already exists", id), err)
 	})
 
@@ -198,7 +198,7 @@ func Test_Add_Object_WithNoVectorizerModule(t *testing.T) {
 
 		vectorRepo.On("Exists", "Foo", id).Return(false, nil).Once()
 
-		_, err := manager.AddObject(ctx, nil, class, nil, "")
+		_, err := manager.AddObject(ctx, nil, class, nil)
 		assert.Equal(t, NewErrInvalidUserInput("invalid object: invalid UUID length: %d", len(id)), err)
 	})
 
@@ -216,7 +216,7 @@ func Test_Add_Object_WithNoVectorizerModule(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 
-		_, err := manager.AddObject(ctx, nil, class, nil, "")
+		_, err := manager.AddObject(ctx, nil, class, nil)
 		assert.Nil(t, err)
 	})
 
@@ -231,7 +231,7 @@ func Test_Add_Object_WithNoVectorizerModule(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 
-		_, err := manager.AddObject(ctx, nil, class, nil, "")
+		_, err := manager.AddObject(ctx, nil, class, nil)
 		assert.Nil(t, err)
 	})
 }
@@ -283,7 +283,7 @@ func Test_Add_Object_WithExternalVectorizerModule(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 
-		res, err := manager.AddObject(ctx, nil, object, nil, "")
+		res, err := manager.AddObject(ctx, nil, object, nil)
 		require.Nil(t, err)
 
 		uuidDuringCreation := vectorRepo.Mock.Calls[0].Arguments.Get(0).(*models.Object).ID
@@ -305,7 +305,7 @@ func Test_Add_Object_WithExternalVectorizerModule(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 
-		res, err := manager.AddObject(ctx, nil, object, nil, "")
+		res, err := manager.AddObject(ctx, nil, object, nil)
 		uuidDuringCreation := vectorRepo.Mock.Calls[1].Arguments.Get(0).(*models.Object).ID
 
 		assert.Nil(t, err)
@@ -327,7 +327,7 @@ func Test_Add_Object_WithExternalVectorizerModule(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 
-		_, err := manager.AddObject(ctx, nil, object, nil, "")
+		_, err := manager.AddObject(ctx, nil, object, nil)
 		assert.Equal(t, NewErrInvalidUserInput("id '%s' already exists", id), err)
 	})
 
@@ -345,7 +345,7 @@ func Test_Add_Object_WithExternalVectorizerModule(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 
-		_, err := manager.AddObject(ctx, nil, object, nil, "")
+		_, err := manager.AddObject(ctx, nil, object, nil)
 		assert.Equal(t, NewErrInvalidUserInput("invalid object: invalid UUID length: %d", len(id)), err)
 	})
 }
@@ -397,7 +397,7 @@ func Test_Add_Object_OverrideVectorizer(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(object.Vector, nil)
 
-		_, err := manager.AddObject(ctx, nil, object, nil, "")
+		_, err := manager.AddObject(ctx, nil, object, nil)
 		require.Nil(t, err)
 
 		vec := vectorRepo.Mock.Calls[0].Arguments.Get(1).([]float32)
@@ -454,7 +454,7 @@ func Test_AddObjectEmptyProperties(t *testing.T) {
 	assert.Nil(t, object.Properties)
 	modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 		Return(nil, nil)
-	addedObject, err := manager.AddObject(ctx, nil, object, nil, "")
+	addedObject, err := manager.AddObject(ctx, nil, object, nil)
 	assert.Nil(t, err)
 	assert.NotNil(t, addedObject.Properties)
 }
@@ -513,7 +513,7 @@ func Test_AddObjectWithUUIDProps(t *testing.T) {
 	}
 	modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 		Return(nil, nil)
-	addedObject, err := manager.AddObject(ctx, nil, object, nil, "")
+	addedObject, err := manager.AddObject(ctx, nil, object, nil)
 	require.Nil(t, err)
 	require.NotNil(t, addedObject.Properties)
 
diff --git a/usecases/objects/authorization_test.go b/usecases/objects/authorization_test.go
index cba0481bc5..303b1c77d7 100644
--- a/usecases/objects/authorization_test.go
+++ b/usecases/objects/authorization_test.go
@@ -86,7 +86,7 @@ func Test_Kinds_Authorization(t *testing.T) {
 			methodName: "MergeObject",
 			additionalArgs: []interface{}{
 				&models.Object{Class: "class", ID: "foo"},
-				(*additional.ReplicationProperties)(nil), "",
+				(*additional.ReplicationProperties)(nil),
 			},
 			expectedVerb:     "update",
 			expectedResource: "objects/class/foo",
@@ -206,7 +206,6 @@ func Test_BatchKinds_Authorization(t *testing.T) {
 				[]*models.Object{},
 				[]*string{},
 				&additional.ReplicationProperties{},
-				"",
 			},
 			expectedVerb:     "create",
 			expectedResource: "batch/objects",
@@ -217,7 +216,6 @@ func Test_BatchKinds_Authorization(t *testing.T) {
 			additionalArgs: []interface{}{
 				[]*models.BatchReference{},
 				&additional.ReplicationProperties{},
-				"",
 			},
 			expectedVerb:     "update",
 			expectedResource: "batch/*",
diff --git a/usecases/objects/batch_add_test.go b/usecases/objects/batch_add_test.go
index 8c2a5ab7da..f4a60a1343 100644
--- a/usecases/objects/batch_add_test.go
+++ b/usecases/objects/batch_add_test.go
@@ -84,7 +84,7 @@ func Test_BatchManager_AddObjects_WithNoVectorizerModule(t *testing.T) {
 		expectedErr := NewErrInvalidUserInput("invalid param 'objects': cannot be empty, need at least" +
 			" one object for batching")
 
-		_, err := manager.AddObjects(ctx, nil, []*models.Object{}, []*string{}, nil, "")
+		_, err := manager.AddObjects(ctx, nil, []*models.Object{}, []*string{}, nil)
 
 		assert.Equal(t, expectedErr, err)
 	})
@@ -108,7 +108,7 @@ func Test_BatchManager_AddObjects_WithNoVectorizerModule(t *testing.T) {
 				Return(nil, nil)
 		}
 
-		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil, "")
+		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil)
 		repoCalledWithObjects := vectorRepo.Calls[0].Arguments[0].(BatchObjects)
 
 		assert.Nil(t, err)
@@ -144,7 +144,7 @@ func Test_BatchManager_AddObjects_WithNoVectorizerModule(t *testing.T) {
 				Return(nil, nil)
 		}
 
-		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil, "")
+		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil)
 		repoCalledWithObjects := vectorRepo.Calls[0].Arguments[0].(BatchObjects)
 
 		assert.Nil(t, err)
@@ -184,7 +184,7 @@ func Test_BatchManager_AddObjects_WithNoVectorizerModule(t *testing.T) {
 				Return(nil, nil)
 		}
 
-		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil, "")
+		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil)
 		repoCalledWithObjects := vectorRepo.Calls[0].Arguments[0].(BatchObjects)
 
 		assert.Nil(t, err)
@@ -222,7 +222,7 @@ func Test_BatchManager_AddObjects_WithNoVectorizerModule(t *testing.T) {
 				Return(nil, nil)
 		}
 
-		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil, "")
+		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil)
 		repoCalledWithObjects := vectorRepo.Calls[0].Arguments[0].(BatchObjects)
 
 		assert.Nil(t, err)
@@ -255,7 +255,7 @@ func Test_BatchManager_AddObjects_WithNoVectorizerModule(t *testing.T) {
 				Return(nil, nil)
 		}
 
-		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil, "")
+		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil)
 		repoCalledWithObjects := vectorRepo.Calls[0].Arguments[0].(BatchObjects)
 
 		assert.Nil(t, err)
@@ -305,7 +305,7 @@ func Test_BatchManager_AddObjects_WithExternalVectorizerModule(t *testing.T) {
 		expectedErr := NewErrInvalidUserInput("invalid param 'objects': cannot be empty, need at least" +
 			" one object for batching")
 
-		_, err := manager.AddObjects(ctx, nil, []*models.Object{}, []*string{}, nil, "")
+		_, err := manager.AddObjects(ctx, nil, []*models.Object{}, []*string{}, nil)
 
 		assert.Equal(t, expectedErr, err)
 	})
@@ -328,7 +328,7 @@ func Test_BatchManager_AddObjects_WithExternalVectorizerModule(t *testing.T) {
 				Return(expectedVector, nil)
 		}
 
-		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil, "")
+		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil)
 		repoCalledWithObjects := vectorRepo.Calls[0].Arguments[0].(BatchObjects)
 
 		assert.Nil(t, err)
@@ -364,7 +364,7 @@ func Test_BatchManager_AddObjects_WithExternalVectorizerModule(t *testing.T) {
 				Return(nil, nil)
 		}
 
-		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil, "")
+		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil)
 		repoCalledWithObjects := vectorRepo.Calls[0].Arguments[0].(BatchObjects)
 
 		assert.Nil(t, err)
@@ -394,7 +394,7 @@ func Test_BatchManager_AddObjects_WithExternalVectorizerModule(t *testing.T) {
 				Return(nil, nil)
 		}
 
-		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil, "")
+		_, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil)
 		repoCalledWithObjects := vectorRepo.Calls[0].Arguments[0].(BatchObjects)
 
 		assert.Nil(t, err)
@@ -464,7 +464,7 @@ func Test_BatchManager_AddObjectsEmptyProperties(t *testing.T) {
 		modulesProvider.On("UpdateVector", mock.Anything, mock.AnythingOfType(FindObjectFn)).
 			Return(nil, nil)
 	}
-	addedObjects, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil, "")
+	addedObjects, err := manager.AddObjects(ctx, nil, objects, []*string{}, nil)
 	assert.Nil(t, err)
 	require.Len(t, addedObjects, 2)
 	require.NotNil(t, addedObjects[0].Object.Properties)
diff --git a/usecases/objects/fakes_for_test.go b/usecases/objects/fakes_for_test.go
index 313bc405e5..c8b88cb4aa 100644
--- a/usecases/objects/fakes_for_test.go
+++ b/usecases/objects/fakes_for_test.go
@@ -180,21 +180,21 @@ func (f *fakeVectorRepo) Query(ctx context.Context, q *QueryInput) (search.Resul
 }
 
 func (f *fakeVectorRepo) PutObject(ctx context.Context, concept *models.Object, vector []float32,
-	repl *additional.ReplicationProperties, tenantKey string,
+	repl *additional.ReplicationProperties,
 ) error {
 	args := f.Called(concept, vector)
 	return args.Error(0)
 }
 
 func (f *fakeVectorRepo) BatchPutObjects(ctx context.Context, batch BatchObjects,
-	repl *additional.ReplicationProperties, tenantKey string,
+	repl *additional.ReplicationProperties,
 ) (BatchObjects, error) {
 	args := f.Called(batch)
 	return batch, args.Error(0)
 }
 
 func (f *fakeVectorRepo) AddBatchReferences(ctx context.Context, batch BatchReferences,
-	repl *additional.ReplicationProperties, tenantKey string,
+	repl *additional.ReplicationProperties,
 ) (BatchReferences, error) {
 	args := f.Called(batch)
 	return batch, args.Error(0)
diff --git a/usecases/objects/merge_test.go b/usecases/objects/merge_test.go
index 554a8367d1..eb1b4eb79d 100644
--- a/usecases/objects/merge_test.go
+++ b/usecases/objects/merge_test.go
@@ -465,7 +465,7 @@ func Test_MergeObject(t *testing.T) {
 			// called during validation of cross-refs only.
 			m.repo.On("Exists", mock.Anything, mock.Anything).Maybe().Return(true, tc.errExists)
 
-			err := m.MergeObject(context.Background(), nil, tc.updated, nil, "")
+			err := m.MergeObject(context.Background(), nil, tc.updated, nil)
 			code := 0
 			if err != nil {
 				code = err.Code
diff --git a/usecases/objects/update_test.go b/usecases/objects/update_test.go
index 726f4ee2aa..316ab0be8b 100644
--- a/usecases/objects/update_test.go
+++ b/usecases/objects/update_test.go
@@ -100,7 +100,7 @@ func Test_UpdateAction(t *testing.T) {
 			ID:         id,
 			Properties: map[string]interface{}{"foo": "baz"},
 		}
-		res, err := manager.UpdateObject(context.Background(), &models.Principal{}, "", id, payload, nil, "")
+		res, err := manager.UpdateObject(context.Background(), &models.Principal{}, "", id, payload, nil)
 		require.Nil(t, err)
 		expected := &models.Object{
 			Class:            "ActionClass",
@@ -155,7 +155,7 @@ func Test_UpdateObject(t *testing.T) {
 	}
 	// the object might not exist
 	m.repo.On("Object", cls, id, mock.Anything, mock.Anything).Return(nil, anyErr).Once()
-	_, err := m.UpdateObject(context.Background(), &models.Principal{}, cls, id, payload, nil, "")
+	_, err := m.UpdateObject(context.Background(), &models.Principal{}, cls, id, payload, nil)
 	if err == nil {
 		t.Fatalf("must return an error if object() fails")
 	}
@@ -179,7 +179,7 @@ func Test_UpdateObject(t *testing.T) {
 		CreationTimeUnix: beforeUpdate,
 		Vector:           vec,
 	}
-	res, err := m.UpdateObject(context.Background(), &models.Principal{}, cls, id, payload, nil, "")
+	res, err := m.UpdateObject(context.Background(), &models.Principal{}, cls, id, payload, nil)
 	require.Nil(t, err)
 	if res.LastUpdateTimeUnix <= beforeUpdate {
 		t.Error("time after update must be greater than time before update ")
diff --git a/usecases/objects/validation/phone_numbers_test.go b/usecases/objects/validation/phone_numbers_test.go
index b8cb7ac013..58d0ce76f6 100644
--- a/usecases/objects/validation/phone_numbers_test.go
+++ b/usecases/objects/validation/phone_numbers_test.go
@@ -159,7 +159,7 @@ func TestPropertyOfTypePhoneNumberValidation(t *testing.T) {
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
 			config := &config.WeaviateConfig{}
-			validator := New(fakeExists, config, nil, "")
+			validator := New(fakeExists, config, nil)
 
 			obj := &models.Object{
 				Class: "Person",
diff --git a/usecases/schema/add_test.go b/usecases/schema/add_test.go
index ca68a33186..b4f3e02331 100644
--- a/usecases/schema/add_test.go
+++ b/usecases/schema/add_test.go
@@ -452,8 +452,7 @@ func TestAddClass(t *testing.T) {
 					},
 				},
 				MultiTenancyConfig: &models.MultiTenancyConfig{
-					Enabled:   true,
-					TenantKey: "textProp",
+					Enabled: true,
 				},
 			}
 			mgr := newSchemaManager()
@@ -463,49 +462,6 @@ func TestAddClass(t *testing.T) {
 			require.Zero(t, class.ShardingConfig.(sharding.Config).DesiredCount)
 		})
 
-		t.Run("multiTenancyConfig missing tenantKey", func(t *testing.T) {
-			mgr := newSchemaManager()
-			err := mgr.AddClass(context.Background(),
-				nil,
-				&models.Class{
-					Class: "NewClass",
-					Properties: []*models.Property{
-						{
-							Name:     "textProp",
-							DataType: []string{"text"},
-						},
-					},
-					MultiTenancyConfig: &models.MultiTenancyConfig{
-						Enabled: true,
-					},
-				},
-			)
-			require.NotNil(t, err)
-			require.Equal(t, "multiTenancyConfig.tenantKey is required", err.Error())
-		})
-
-		t.Run("multiTenancyConfig.tenantKey invalid prop type", func(t *testing.T) {
-			mgr := newSchemaManager()
-			err := mgr.AddClass(context.Background(),
-				nil,
-				&models.Class{
-					Class: "NewClass",
-					Properties: []*models.Property{
-						{
-							Name:     "intProp",
-							DataType: []string{"int"},
-						},
-					},
-					MultiTenancyConfig: &models.MultiTenancyConfig{
-						Enabled:   true,
-						TenantKey: "intProp",
-					},
-				},
-			)
-			require.NotNil(t, err)
-			require.Equal(t, "invalid multiTenancyConfig.tenantKey \"intProp\". tenantKey must be 'text' or 'uuid'", err.Error())
-		})
-
 		t.Run("multiTenancyConfig and shardingConfig both provided", func(t *testing.T) {
 			mgr := newSchemaManager()
 			err := mgr.AddClass(context.Background(),
@@ -519,8 +475,7 @@ func TestAddClass(t *testing.T) {
 						},
 					},
 					MultiTenancyConfig: &models.MultiTenancyConfig{
-						Enabled:   true,
-						TenantKey: "uuidProp",
+						Enabled: true,
 					},
 					ShardingConfig: sharding.Config{DesiredCount: 2},
 				},
diff --git a/usecases/schema/tenant_test.go b/usecases/schema/tenant_test.go
index 1b69c72c6b..d77ccb0229 100644
--- a/usecases/schema/tenant_test.go
+++ b/usecases/schema/tenant_test.go
@@ -23,7 +23,7 @@ import (
 func TestAddTenants(t *testing.T) {
 	var (
 		ctx        = context.Background()
-		mt         = &models.MultiTenancyConfig{Enabled: true, TenantKey: "uUID"}
+		mt         = &models.MultiTenancyConfig{Enabled: true}
 		tenants    = []*models.Tenant{{Name: "USER1"}, {Name: "USER2"}}
 		cls        = "C1"
 		properties = []*models.Property{
@@ -73,7 +73,7 @@ func TestAddTenants(t *testing.T) {
 			tenants: tenants,
 			initial: &models.Class{
 				Class:              cls,
-				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: false, TenantKey: "uUID"},
+				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: false},
 				Properties:         properties,
 				ReplicationConfig:  repConfig,
 			},
@@ -85,7 +85,7 @@ func TestAddTenants(t *testing.T) {
 			tenants: []*models.Tenant{{Name: "A"}, {Name: ""}, {Name: "B"}},
 			initial: &models.Class{
 				Class:              cls,
-				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true, TenantKey: "uUID"},
+				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true},
 				Properties:         properties,
 				ReplicationConfig:  repConfig,
 			},
@@ -97,7 +97,7 @@ func TestAddTenants(t *testing.T) {
 			tenants: []*models.Tenant{{Name: "A"}, {Name: "B"}},
 			initial: &models.Class{
 				Class:              cls,
-				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true, TenantKey: "uUID"},
+				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true},
 				Properties:         properties,
 				ReplicationConfig:  repConfig,
 			},
@@ -128,7 +128,7 @@ func TestAddTenants(t *testing.T) {
 func TestDeleteTenants(t *testing.T) {
 	var (
 		ctx     = context.Background()
-		mt      = &models.MultiTenancyConfig{Enabled: true, TenantKey: "uUID"}
+		mt      = &models.MultiTenancyConfig{Enabled: true}
 		tenants = []*models.Tenant{
 			{Name: "USER1"},
 			{Name: "USER2"},
@@ -183,7 +183,7 @@ func TestDeleteTenants(t *testing.T) {
 			tenants: tenants,
 			initial: &models.Class{
 				Class:              cls,
-				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: false, TenantKey: "uUID"},
+				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: false},
 				Properties:         properties,
 				ReplicationConfig:  repConfig,
 			},
@@ -195,7 +195,7 @@ func TestDeleteTenants(t *testing.T) {
 			tenants: []*models.Tenant{{Name: "A"}, {Name: ""}, {Name: "B"}},
 			initial: &models.Class{
 				Class:              cls,
-				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true, TenantKey: "uUID"},
+				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true},
 				Properties:         properties,
 				ReplicationConfig:  repConfig,
 			},
@@ -207,7 +207,7 @@ func TestDeleteTenants(t *testing.T) {
 			tenants: tenants[:2],
 			initial: &models.Class{
 				Class:              cls,
-				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true, TenantKey: "uUID"},
+				MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true},
 				Properties:         properties,
 				ReplicationConfig:  repConfig,
 			},