diff --git a/src/main/java/it/inaf/oats/vospace/JobService.java b/src/main/java/it/inaf/oats/vospace/JobService.java
index 122ad4c8ba365ade407444dffa9f7ccd734a480c..8d77a2bf7b14710be5ae7bba999873e58151801e 100644
--- a/src/main/java/it/inaf/oats/vospace/JobService.java
+++ b/src/main/java/it/inaf/oats/vospace/JobService.java
@@ -93,7 +93,7 @@ public class JobService {
             Transfer transfer = uriService.getTransfer(job);
 
             ExecutionPhase phase;
-            if (transfer.getProtocols().stream().anyMatch(p -> "ia2:async-recall".equals(p.getUri()))) {
+            if (isAsyncRecall(transfer)) {
                 // Async recall from tape jobs are queued. They will be started by VOSpace transfer service
                 phase = ExecutionPhase.QUEUED;
             } else {
@@ -132,11 +132,13 @@ public class JobService {
 
     private Transfer handlePullToVoSpace(JobSummary job, Transfer transfer) {
 
+        if (isAsyncRecall(transfer)) {
+            asyncTransfService.startJob(job);
+            return transfer;
+        }
+
         for (Protocol protocol : transfer.getProtocols()) {
             switch (protocol.getUri()) {
-                case "ia2:async-recall":
-                    asyncTransfService.startJob(job);
-                    return transfer;
                 case "ivo://ivoa.net/vospace/core#httpget":
                     if (transfer.getTarget().size() != 1) {
                         throw new InvalidArgumentException("Invalid target size for pullToVoSpace: " + transfer.getTarget().size());
@@ -158,6 +160,11 @@ public class JobService {
         throw new InvalidArgumentException("Transfer contains no protocols");
     }
 
+    private boolean isAsyncRecall(Transfer transfer) {
+        return transfer.getView() != null
+                && "ivo://ia2.inaf.it/vospace/views#async-recall".equals(transfer.getView().getUri());
+    }
+    
     private void handleMoveNode(JobSummary jobSummary, Transfer transfer) {
         // User data must be extracted before starting the new thread
         // to avoid the "No thread-bound request found" exception
diff --git a/src/test/java/it/inaf/oats/vospace/AsyncTransferServiceTest.java b/src/test/java/it/inaf/oats/vospace/AsyncTransferServiceTest.java
index da76598edebee54fecad120a0ef4c9c3870b2474..b426531e4e14bbb3a05b0f4404459559736ab052 100644
--- a/src/test/java/it/inaf/oats/vospace/AsyncTransferServiceTest.java
+++ b/src/test/java/it/inaf/oats/vospace/AsyncTransferServiceTest.java
@@ -5,12 +5,14 @@
  */
 package it.inaf.oats.vospace;
 
+import it.inaf.oats.vospace.datamodel.Views;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import net.ivoa.xml.uws.v1.JobSummary;
-import net.ivoa.xml.vospace.v2.Protocol;
+import net.ivoa.xml.vospace.v2.Param;
 import net.ivoa.xml.vospace.v2.Transfer;
+import net.ivoa.xml.vospace.v2.View;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.fail;
 import org.junit.jupiter.api.Test;
@@ -26,7 +28,7 @@ import redis.clients.jedis.Jedis;
 @ExtendWith(MockitoExtension.class)
 public class AsyncTransferServiceTest {
 
-    private static final String JSON_JOB = "{\"jobId\":\"job_id\",\"runId\":null,\"ownerId\":null,\"phase\":null,\"quote\":null,\"creationTime\":null,\"startTime\":null,\"endTime\":null,\"executionDuration\":0,\"destruction\":null,\"parameters\":null,\"results\":[],\"errorSummary\":null,\"jobInfo\":{\"transfer\":{\"target\":[\"vos://example.com!vospace/my-node\"],\"direction\":\"pullToVoSpace\",\"view\":null,\"protocols\":[],\"keepBytes\":null,\"version\":null,\"param\":[]}},\"version\":null}\n";
+    private static final String JSON_JOB = "{\"jobId\":\"job_id\",\"runId\":null,\"ownerId\":null,\"phase\":null,\"quote\":null,\"creationTime\":null,\"startTime\":null,\"endTime\":null,\"executionDuration\":0,\"destruction\":null,\"parameters\":null,\"results\":[],\"errorSummary\":null,\"jobInfo\":{\"transfer\":{\"target\":[\"vos://example.com!vospace/my-node\"],\"direction\":\"pullToVoSpace\",\"view\":{\"param\":[{\"value\":\"file1.txt\",\"uri\":\"ivo://ia2.inaf.it/vospace/views#async-recall/include\"},{\"value\":\"file2.txt\",\"uri\":\"ivo://ia2.inaf.it/vospace/views#async-recall/include\"}],\"uri\":\"ivo://ia2.inaf.it/vospace/views#async-recall\",\"original\":true},\"protocols\":[],\"keepBytes\":false,\"version\":null,\"param\":[]}},\"version\":null}";
 
     @Test
     public void testRedisRpc() {
@@ -53,19 +55,32 @@ public class AsyncTransferServiceTest {
             try {
                 asyncTransferService.startJob(getFakeJob());
                 fail();
-            } catch(IllegalStateException ex) {
+            } catch (IllegalStateException ex) {
             }
         }
     }
-    
+
     private JobSummary getFakeJob() {
         Transfer transfer = new Transfer();
         transfer.setDirection("pullToVoSpace");
-        Protocol protocol = new Protocol();
-        protocol.setUri("ia2:async-recall");
-        transfer.getProtocols().add(protocol);
+
         transfer.setTarget(Arrays.asList("vos://example.com!vospace/my-node"));
 
+        View view = new View();
+        view.setUri(Views.ASYNC_RECALL_VIEW_URI);
+
+        Param p1 = new Param();
+        p1.setUri(Views.ASYNC_RECALL_VIEW_URI + "/include");
+        p1.setValue("file1.txt");
+        view.getParam().add(p1);
+
+        Param p2 = new Param();
+        p2.setUri(Views.ASYNC_RECALL_VIEW_URI + "/include");
+        p2.setValue("file2.txt");
+        view.getParam().add(p2);
+
+        transfer.setView(view);
+
         JobSummary job = new JobSummary();
         job.setJobId("job_id");
 
diff --git a/src/test/java/it/inaf/oats/vospace/JobServiceTest.java b/src/test/java/it/inaf/oats/vospace/JobServiceTest.java
index f276397fc5a30473e0a04465863632d7e7c9d6ff..5f634b3fcfc8aae7da3561cceacf818a73421db0 100644
--- a/src/test/java/it/inaf/oats/vospace/JobServiceTest.java
+++ b/src/test/java/it/inaf/oats/vospace/JobServiceTest.java
@@ -5,6 +5,7 @@
  */
 package it.inaf.oats.vospace;
 
+import it.inaf.oats.vospace.datamodel.Views;
 import it.inaf.oats.vospace.exception.NodeBusyException;
 import it.inaf.oats.vospace.persistence.JobDAO;
 import java.util.ArrayList;
@@ -15,6 +16,7 @@ import net.ivoa.xml.uws.v1.ExecutionPhase;
 import net.ivoa.xml.uws.v1.JobSummary;
 import net.ivoa.xml.vospace.v2.Protocol;
 import net.ivoa.xml.vospace.v2.Transfer;
+import net.ivoa.xml.vospace.v2.View;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -229,9 +231,9 @@ public class JobServiceTest {
     private Transfer getTapeTransfer() {
         Transfer transfer = new Transfer();
         transfer.setDirection("pullToVoSpace");
-        Protocol protocol = new Protocol();
-        protocol.setUri("ia2:async-recall");
-        transfer.getProtocols().add(protocol);
+        View view = new View();
+        view.setUri(Views.ASYNC_RECALL_VIEW_URI);
+        transfer.setView(view);
         return transfer;
     }
 
diff --git a/src/test/resources/pullToVoSpace-tape.xml b/src/test/resources/pullToVoSpace-tape.xml
index 51e99e9f8218a90b89f960bf4173e5e598e4b577..15102d9db459145f18090f219e52771ba9ca1d5e 100644
--- a/src/test/resources/pullToVoSpace-tape.xml
+++ b/src/test/resources/pullToVoSpace-tape.xml
@@ -1,5 +1,9 @@
 <vos:transfer xmlns:vos="http://www.ivoa.net/xml/VOSpace/v2.0" version="2.1">
     <vos:target>vos://example.com!vospace/mynode</vos:target>
     <vos:direction>pullToVoSpace</vos:direction>
-    <vos:protocol uri="ia2:async-recall" />
+    <vos:view uri="ivo://ia2.inaf.it/vospace/views#async-recall">
+        <vos:param uri="ivo://ia2.inaf.it/vospace/views#async-recall/include">test1.txt</vos:param>
+        <vos:param uri="ivo://ia2.inaf.it/vospace/views#async-recall/include">test2.txt</vos:param>
+        <vos:param uri="ivo://ia2.inaf.it/vospace/views#async-recall/include">test3.txt</vos:param>
+    </vos:view>
 </vos:transfer>
\ No newline at end of file