diff --git a/src/main/java/org/caosdb/server/CaosDBServer.java b/src/main/java/org/caosdb/server/CaosDBServer.java
index 4b7c0fe11ecb0c2391e5548ed6e37ede416e1343..9f04f75e0dd44bf20e026f57a9766a32e9137492 100644
--- a/src/main/java/org/caosdb/server/CaosDBServer.java
+++ b/src/main/java/org/caosdb/server/CaosDBServer.java
@@ -80,6 +80,7 @@ import org.caosdb.server.resource.UserResource;
 import org.caosdb.server.resource.UserRolesResource;
 import org.caosdb.server.resource.Webinterface;
 import org.caosdb.server.resource.WebinterfaceBuildNumber;
+import org.caosdb.server.resource.transaction.DeleteEntityResource;
 import org.caosdb.server.resource.transaction.EntityNamesResource;
 import org.caosdb.server.resource.transaction.EntityResource;
 import org.caosdb.server.scripting.ScriptingPermissions;
@@ -692,14 +693,32 @@ public class CaosDBServer extends Application {
     authenticator.setNext(authorizer);
 
     protectedRouter.attach("/scripting", ScriptingResource.class);
+    protectedRouter.attach("/delete/entities/", DeleteEntityResource.class);
+    protectedRouter.attach("/delete/entities", DeleteEntityResource.class);
+    protectedRouter.attach("/entities/names", EntityNamesResource.class);
+    protectedRouter.attach("/entities", EntityResource.class);
+    protectedRouter.attach("/entities/", EntityResource.class);
+    protectedRouter
+        .attach("/entities/{specifier}", EntityResource.class)
+        .getTemplate()
+        .getDefaultVariable()
+        .setType(Variable.TYPE_URI_PATH);
     protectedRouter.attach("/Entities/names", EntityNamesResource.class);
     protectedRouter.attach("/Entity/names", EntityNamesResource.class);
     protectedRouter.attach("/Entities", EntityResource.class);
     protectedRouter.attach("/Entities/", EntityResource.class);
-    protectedRouter.attach("/Entities/{specifier}", EntityResource.class);
+    protectedRouter
+        .attach("/Entities/{specifier}", EntityResource.class)
+        .getTemplate()
+        .getDefaultVariable()
+        .setType(Variable.TYPE_URI_PATH);
     protectedRouter.attach("/Entity", EntityResource.class);
     protectedRouter.attach("/Entity/", EntityResource.class);
-    protectedRouter.attach("/Entity/{specifier}", EntityResource.class);
+    protectedRouter
+        .attach("/Entity/{specifier}", EntityResource.class)
+        .getTemplate()
+        .getDefaultVariable()
+        .setType(Variable.TYPE_URI_PATH);
     protectedRouter.attach("/Users", UserResource.class);
     protectedRouter.attach("/Users/", UserResource.class);
     protectedRouter.attach("/Users/{specifier}", UserResource.class);
@@ -713,8 +732,16 @@ public class CaosDBServer extends Application {
     protectedRouter.attach("/UserRoles/{specifier}", UserRolesResource.class);
     protectedRouter.attach("/EntityPermissions", EntityPermissionsResource.class);
     protectedRouter.attach("/EntityPermissions/", EntityPermissionsResource.class);
-    protectedRouter.attach("/EntityPermissions/{specifier}", EntityPermissionsResource.class);
-    protectedRouter.attach("/Owner/{specifier}", EntityOwnerResource.class);
+    protectedRouter
+        .attach("/EntityPermissions/{specifier}", EntityPermissionsResource.class)
+        .getTemplate()
+        .getDefaultVariable()
+        .setType(Variable.TYPE_URI_PATH);
+    protectedRouter
+        .attach("/Owner/{specifier}", EntityOwnerResource.class)
+        .getTemplate()
+        .getDefaultVariable()
+        .setType(Variable.TYPE_URI_PATH);
     protectedRouter.attach(
         "/FileSystem",
         new Redirector(getContext(), "/FileSystem/", Redirector.MODE_CLIENT_PERMANENT));
diff --git a/src/main/java/org/caosdb/server/ServerProperties.java b/src/main/java/org/caosdb/server/ServerProperties.java
index 93a0c7473be1c31565e4b159ba55e01d557687e7..0885ea75b1c0b64a129e55b471306472c38c5134 100644
--- a/src/main/java/org/caosdb/server/ServerProperties.java
+++ b/src/main/java/org/caosdb/server/ServerProperties.java
@@ -163,7 +163,9 @@ public class ServerProperties extends Properties implements Observable {
     final String basepath = System.getProperty("user.dir");
 
     final URL url = CaosDBServer.class.getResource("/build.properties");
-    serverProperties.load(url.openStream());
+    if (url != null) {
+      serverProperties.load(url.openStream());
+    }
 
     // load standard config
     loadConfigFile(serverProperties, new File(basepath + "/conf/core/server.conf"));
diff --git a/src/main/java/org/caosdb/server/entity/StringIds.java b/src/main/java/org/caosdb/server/entity/StringIds.java
index 7fd69c2f34cd22376a2d0abf7f04956a2954fbe4..2b07f0d814f4be9f238e45fff3a6109668225052 100644
--- a/src/main/java/org/caosdb/server/entity/StringIds.java
+++ b/src/main/java/org/caosdb/server/entity/StringIds.java
@@ -31,21 +31,43 @@ import org.caosdb.server.utils.ServerMessages;
  */
 public class StringIds extends EntityIdRegistryStrategy {
 
+  private String prefix;
+
   public StringIds(Transaction<?> t) {
+    this("", t);
+  }
+
+  public StringIds(String prefix, Transaction<?> t) {
     super(t);
+    this.prefix = prefix;
+  }
+
+  public String getPrefix() {
+    return prefix;
   }
 
   @Override
   public String generate() {
-    return UUID.randomUUID().toString();
+    String uuid = UUID.randomUUID().toString();
+    if (prefix == null) {
+      return uuid;
+    }
+    StringBuilder sb = new StringBuilder(prefix.length() + uuid.length());
+    sb.append(prefix).append(uuid);
+    return sb.toString();
   }
 
   @Override
   public boolean matchIdPattern(String id) {
+    if (prefix.length() > 0 && !id.startsWith(prefix)) {
+      // not starting with prefix
+      return false;
+    }
     try {
-      UUID.fromString(id);
+      UUID.fromString(id.substring(prefix.length()));
       return true;
     } catch (IllegalArgumentException e) {
+      // could not parse as UUID string
       return false;
     }
   }
diff --git a/src/main/java/org/caosdb/server/entity/container/RetrieveContainer.java b/src/main/java/org/caosdb/server/entity/container/RetrieveContainer.java
index 99262f56d15d90ba86fb1a9cd8fd76b90c4dbf22..9bce6c1ee1c37fc1e47ee4bc53d0be3e35978484 100644
--- a/src/main/java/org/caosdb/server/entity/container/RetrieveContainer.java
+++ b/src/main/java/org/caosdb/server/entity/container/RetrieveContainer.java
@@ -21,7 +21,7 @@
  */
 package org.caosdb.server.entity.container;
 
-import java.util.HashMap;
+import java.util.Map;
 import org.apache.shiro.subject.Subject;
 import org.caosdb.server.entity.EntityID;
 import org.caosdb.server.entity.RetrieveEntity;
@@ -51,7 +51,7 @@ public class RetrieveContainer extends TransactionContainer {
       final Subject user,
       final Long timestamp,
       final String srid,
-      final HashMap<String, String> flags) {
+      final Map<String, String> flags) {
     super(user, timestamp, srid, flags);
   }
 
diff --git a/src/main/java/org/caosdb/server/entity/container/TransactionContainer.java b/src/main/java/org/caosdb/server/entity/container/TransactionContainer.java
index 049f54cd1ded0ece71c7082ddc960c4246ef0b28..3f7769e06d2f9a331d747a3f38e8bd054c76e37a 100644
--- a/src/main/java/org/caosdb/server/entity/container/TransactionContainer.java
+++ b/src/main/java/org/caosdb/server/entity/container/TransactionContainer.java
@@ -24,6 +24,7 @@ package org.caosdb.server.entity.container;
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import org.apache.shiro.subject.Subject;
 import org.caosdb.server.CaosDBServer;
 import org.caosdb.server.database.misc.TransactionBenchmark;
@@ -65,7 +66,7 @@ public class TransactionContainer extends Container<EntityInterface>
       final Subject user,
       final Long timestamp,
       final String srid,
-      final HashMap<String, String> flags) {
+      final Map<String, String> flags) {
     this(user, timestamp, srid);
     setFlags(flags);
   }
@@ -96,9 +97,9 @@ public class TransactionContainer extends Container<EntityInterface>
     this.messages.add(m);
   }
 
-  private HashMap<String, String> flags = null;
+  private Map<String, String> flags = null;
 
-  public HashMap<String, String> getFlags() {
+  public Map<String, String> getFlags() {
     return this.flags;
   }
 
@@ -167,7 +168,7 @@ public class TransactionContainer extends Container<EntityInterface>
     return null;
   }
 
-  public void setFlags(final HashMap<String, String> flags) {
+  public void setFlags(final Map<String, String> flags) {
     this.flags = flags;
   }
 
diff --git a/src/main/java/org/caosdb/server/entity/wrapper/Parent.java b/src/main/java/org/caosdb/server/entity/wrapper/Parent.java
index a2116ac3d0492e8c12487a5e9d6ddafc82b91df8..f4b395f3b818b2de3f7873bac187776ea7ec0d01 100644
--- a/src/main/java/org/caosdb/server/entity/wrapper/Parent.java
+++ b/src/main/java/org/caosdb/server/entity/wrapper/Parent.java
@@ -23,7 +23,9 @@
 package org.caosdb.server.entity.wrapper;
 
 import org.caosdb.server.entity.Affiliation;
+import org.caosdb.server.entity.EntityID;
 import org.caosdb.server.entity.EntityInterface;
+import org.caosdb.server.entity.RetrieveEntity;
 import org.caosdb.server.entity.xml.ParentToElementStrategy;
 
 public class Parent extends EntityWrapper {
@@ -35,6 +37,10 @@ public class Parent extends EntityWrapper {
     setToElementStragegy(new ParentToElementStrategy());
   }
 
+  public Parent(EntityID id) {
+    this(new RetrieveEntity(id));
+  }
+
   public void setEntity(final EntityInterface entity) {
     super.entity = entity;
   }
diff --git a/src/main/java/org/caosdb/server/grpc/GRPCServer.java b/src/main/java/org/caosdb/server/grpc/GRPCServer.java
index 494ce94706eff75415264b175f58cdaf16a2a442..37b91cfc7020507366bbbea6bb8a07376b5f5c28 100644
--- a/src/main/java/org/caosdb/server/grpc/GRPCServer.java
+++ b/src/main/java/org/caosdb/server/grpc/GRPCServer.java
@@ -199,7 +199,7 @@ public class GRPCServer {
 
     boolean started = false;
     final String port_https_str = getServerProperty(ServerProperties.KEY_GRPC_SERVER_PORT_HTTPS);
-    if (port_https_str != null && !port_https_str.isEmpty()) {
+    if (port_https_str != null && !port_https_str.isBlank()) {
       final Integer port_https = Integer.parseInt(port_https_str);
       final Server server = instance.buildServer(port_https, true);
       CaosDBServer.addPreShutdownHook(new ServerStopper(server));
diff --git a/src/main/java/org/caosdb/server/jobs/core/CheckEntityId.java b/src/main/java/org/caosdb/server/jobs/core/CheckEntityId.java
index 712b0d0be9da4a50303f7d24d597022934e9c803..3d2694833f0aec147c4bc38f79e40035b01459f7 100644
--- a/src/main/java/org/caosdb/server/jobs/core/CheckEntityId.java
+++ b/src/main/java/org/caosdb/server/jobs/core/CheckEntityId.java
@@ -18,7 +18,7 @@ public class CheckEntityId extends ContainerJob {
 
   private void checkEntityID(EntityInterface e) {
     try {
-      if (e.hasId()) {
+      if (e.hasId() && !e.getId().isTemporary()) {
         getTransaction().assertMatchIdPattern(e.getId().toString());
       }
     } catch (Message m) {
diff --git a/src/main/java/org/caosdb/server/permissions/EntityPermission.java b/src/main/java/org/caosdb/server/permissions/EntityPermission.java
index 1cfe9901ad2fdf0067d7cd58712c2caa506ac73b..4b344cde2a6e365129d614252c51294020d9a3f1 100644
--- a/src/main/java/org/caosdb/server/permissions/EntityPermission.java
+++ b/src/main/java/org/caosdb/server/permissions/EntityPermission.java
@@ -100,7 +100,7 @@ public class EntityPermission extends Permission {
         return p;
       }
     }
-    throw new IllegalArgumentException("Permission is not defined.");
+    throw new IllegalArgumentException("Permission is not defined: " + name);
   }
 
   public static EntityPermission getEntityPermission(final int bitNumber) {
diff --git a/src/main/java/org/caosdb/server/query/CQLParser.g4 b/src/main/java/org/caosdb/server/query/CQLParser.g4
index 8615bae31fae67eb0bd3315f664bfa708db61618..380c3c74c25869bf580368e7d772c7df39f56563 100644
--- a/src/main/java/org/caosdb/server/query/CQLParser.g4
+++ b/src/main/java/org/caosdb/server/query/CQLParser.g4
@@ -191,10 +191,21 @@ idfilter returns [IDFilter filter] locals [String o, String v, String a]
     (
         OPERATOR {$o = $OPERATOR.text;}
         WHITE_SPACE?
-        value {$v = $value.str;}
+        (
+        	value {$v = $value.str;}
+    		| pid {$v = $pid.text;}
+    	)
     )?
 ;
 
+/**
+ * A Handle PID <prefix/suffix> e.g. "21.1234/sdfg"
+ */
+pid
+:
+    (~(WHITE_SPACE | SLASH ))+ SLASH (~(WHITE_SPACE))+
+;
+
 /**
  * Transaction filter (e.g INSERTED BY ME).
  */
diff --git a/src/main/java/org/caosdb/server/query/IDFilter.java b/src/main/java/org/caosdb/server/query/IDFilter.java
index 8011139796abff42c0e8109621c849d3e6328137..535d23d982f2709b38de82580fc72a3482e4392d 100644
--- a/src/main/java/org/caosdb/server/query/IDFilter.java
+++ b/src/main/java/org/caosdb/server/query/IDFilter.java
@@ -134,4 +134,9 @@ public class IDFilter implements EntityFilterInterface {
     sb.append(")");
     return sb.toString();
   }
+
+  @Override
+  public String toString() {
+    return getCacheKey();
+  }
 }
diff --git a/src/main/java/org/caosdb/server/resource/transaction/DeleteEntityResource.java b/src/main/java/org/caosdb/server/resource/transaction/DeleteEntityResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..6150730c20f8f6625205b8c0c5a3508295071bd7
--- /dev/null
+++ b/src/main/java/org/caosdb/server/resource/transaction/DeleteEntityResource.java
@@ -0,0 +1,52 @@
+package org.caosdb.server.resource.transaction;
+
+import java.util.List;
+import org.caosdb.server.entity.DeleteEntity;
+import org.caosdb.server.entity.EntityID;
+import org.caosdb.server.entity.UpdateEntity;
+import org.caosdb.server.entity.container.WritableContainer;
+import org.caosdb.server.transaction.WriteTransaction;
+import org.caosdb.server.transaction.WriteTransactionInterface;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.restlet.data.Status;
+import org.restlet.representation.Representation;
+
+public class DeleteEntityResource extends EntityResource {
+
+  @Override
+  protected Representation httpDeleteInChildClass() throws Exception {
+    getResponse().setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
+    return null;
+  }
+
+  @Override
+  protected Representation httpPutInChildClass(Representation entity) {
+    getResponse().setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
+    return null;
+  }
+
+  @Override
+  protected Representation httpPostInChildClass(Representation entity)
+      throws xmlNotWellFormedException, Exception {
+    final WritableContainer entityContainer =
+        new WritableContainer(getUser(), getTimestamp(), getSRID(), getFlags());
+    final Document doc = new Document();
+
+    List<Element> updateEntities;
+    updateEntities = parseEntity(getRequest().getEntity()).getRootElement().getChildren();
+
+    for (final Element e : updateEntities) {
+      entityContainer.add(new DeleteEntity(new EntityID(new UpdateEntity(e).getId().toString())));
+    }
+
+    final WriteTransactionInterface update = new WriteTransaction(entityContainer);
+    update.execute();
+
+    final Element rootElem = generateRootElement();
+    entityContainer.addToElement(rootElem);
+    doc.setRootElement(rootElem);
+
+    return ok(doc);
+  }
+}
diff --git a/src/test/java/org/caosdb/server/query/TestCQL.java b/src/test/java/org/caosdb/server/query/TestCQL.java
index 9ca5904a5b851a4a32de5f2328647b64fa05cfec..7f1461a6e4554167f43ceb1194452fde2232f21c 100644
--- a/src/test/java/org/caosdb/server/query/TestCQL.java
+++ b/src/test/java/org/caosdb/server/query/TestCQL.java
@@ -284,6 +284,9 @@ public class TestCQL {
       "FIND ENTITY WHICH HAS A PROPERTY LIKE '*with double*' AND A PROPERTY LIKE '*and single*' AND A PROPERTY LIKE '*what\\'s wrong?*' AND A PROPERTY LIKE '*\\'*' AND A PROPERTY LIKE '*nothin\\'*' AND A PROPERTY LIKE '*\"\\'bla*'";
   String issue203a = "FIND WHICH ( HAS pname )";
   String issue203b = "FIND WHICH ( HAS pname1 AND REFERENCES pname2 )";
+  String pid1 = "FIND ENTITY WITH ID = 21.1234/suffix";
+  String pid2 =
+      "FIND TypeA WHICH IS REFERENCED BY TypeB WITH ID=21.T11965/bd33f91e-bfdd-49f4-b664-8cd6dfe30130";
 
   @Test
   public void testQuery1()
@@ -7130,4 +7133,49 @@ public class TestCQL {
       no = no + 1;
     }
   }
+
+  @Test
+  public void testPid1() {
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.pid1));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+
+    // 4 children: FIND, ENTITY, WHICHCLAUSE, EOF
+    assertEquals(4, sfq.getChildCount());
+    assertEquals(Query.Role.ENTITY, sfq.r);
+    assertNull(sfq.e);
+    assertEquals("WITH ID = 21.1234/suffix", sfq.getChild(2).getText());
+    ParseTree which = sfq.getChild(2);
+    assertEquals("ID = 21.1234/suffix", which.getChild(1).getText());
+
+    assertTrue(sfq.filter instanceof IDFilter);
+    assertEquals("ID(,=,21.1234/suffix)", sfq.filter.toString());
+  }
+
+  @Test
+  public void testPid2() {
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.pid2));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+
+    // 4 children: FIND, ENTITY, WHICHCLAUSE, EOF
+    assertEquals(5, sfq.getChildCount());
+    assertNull(sfq.r);
+    assertEquals("TypeA", sfq.e.str);
+    assertTrue(sfq.filter instanceof Backreference);
+    Backreference backRef = (Backreference) sfq.filter;
+    assertEquals(
+        "ID(,=,21.T11965/bd33f91e-bfdd-49f4-b664-8cd6dfe30130)",
+        backRef.getSubProperty().getFilter().toString());
+  }
 }