diff --git a/library/Class/WebService/OAI/Request/ListIdentifiers.php b/library/Class/WebService/OAI/Request/ListIdentifiers.php
index ade1c8387b3e64fe1958640320e3c92048672de5..261ad44cfafc945eda453fb58719bf7b26bf06ab 100644
--- a/library/Class/WebService/OAI/Request/ListIdentifiers.php
+++ b/library/Class/WebService/OAI/Request/ListIdentifiers.php
@@ -21,7 +21,7 @@
 
 class Class_WebService_OAI_Request_ListIdentifiers {
 
-  const IDENTIFIERS_BY_PAGE = 100;
+  static int $identifiers_by_page = 100;
 
 
   protected
@@ -122,16 +122,18 @@ class Class_WebService_OAI_Request_ListIdentifiers {
     if ( ! $this->_catalogue->hasRecords())
       return $builder->error(['code' => 'noRecordsMatch']);
 
-    if (!$this->_token && static::IDENTIFIERS_BY_PAGE < $this->_total_count)
-      $this->_token = new Class_WebService_OAI_ResumptionToken($this->_params);
+    if ($this->_shouldDisplayResumptionToken())
+      $this->_token = $this->_buildToken();
 
     $page_number = $this->_token
       ? $this->_token->pageNumber()
       : 1;
 
     $this->_notices = Class_Catalogue::getNoticesByPreferences(['id_catalogue' => $this->_catalogue->getId(),
-                                                                'page' => $page_number,
-                                                                'page_size' => self::IDENTIFIERS_BY_PAGE]);
+                                                                'start_limit' => $page_number==1
+                                                                ? 0
+                                                                : ($page_number -1) *self::$identifiers_by_page + 1,
+                                                                'nb_notices' => self::$identifiers_by_page]);
     if (empty($this->_notices))
       return $builder->error(['code' => 'noRecordsMatch']);
   }
@@ -143,6 +145,25 @@ class Class_WebService_OAI_Request_ListIdentifiers {
   }
 
 
+  protected function _buildToken() : Class_WebService_OAI_ResumptionToken{
+    return $this->_resumptionToken
+      ? Class_WebService_OAI_ResumptionToken::fromString($this->_resumptionToken)
+      : new Class_WebService_OAI_ResumptionToken($this->_params,
+                                                 $this->_token
+                                                 ? $this
+                                                 ->_token
+                                                 ->pageNumber()
+                                                 : 1);
+  }
+
+
+  protected function _shouldDisplayResumptionToken(){
+    return $this->_token
+      ? ($this->_token->pageNumber() * static::$identifiers_by_page) <= $this->_catalogue->getNoticesCount()
+      : static::$identifiers_by_page < $this->_catalogue->getNoticesCount();
+  }
+
+
   public function getToken() {
     return $this->_token;
   }
@@ -166,8 +187,10 @@ class Class_WebService_OAI_Request_ListIdentifiers {
 
 
   public function renderResumptionTokenOn($builder) {
-    return $this->_token
-      ? $this->_token->renderOn($builder, $this->_total_count)
+    return $this->_shouldDisplayResumptionToken()
+      ? $this->_token->renderOn($builder, $this->_total_count
+                                ? $this->_total_count
+                                : $this->_catalogue->getNoticesCount())
       : '';
   }
 
diff --git a/library/Class/WebService/OAI/ResumptionToken.php b/library/Class/WebService/OAI/ResumptionToken.php
index 5d521a95f90485fb08d4d9de9d3543840e976a20..8743388a9150e02b47cd168064afd5eb8844c548 100644
--- a/library/Class/WebService/OAI/ResumptionToken.php
+++ b/library/Class/WebService/OAI/ResumptionToken.php
@@ -23,9 +23,8 @@
 class Class_WebService_OAI_ResumptionToken {
   const PARAM_SEPARATOR = '!';
 
-  protected
-    $_params,
-    $_page_number = 1;
+  protected array $_params =[];
+  protected int $_page_number = 1;
 
 
   public static function fromString($value) {
@@ -74,12 +73,12 @@ class Class_WebService_OAI_ResumptionToken {
   public function renderOn($builder, $complete_list_size) {
     return $builder->resumptionToken(['completeListSize' => $complete_list_size,
                                       'cursor' => $this->_cursor()],
-                                     $builder->cdata($this->__toString()));
+                                     $this->__toString());
   }
 
 
   protected function _cursor() {
-    return ($this->_page_number-1) * 100;
+    return ($this->_page_number-1) * Class_WebService_OAI_Request_ListIdentifiers::$identifiers_by_page;
   }
 
 
diff --git a/library/Class/WebService/OAIHarvester.php b/library/Class/WebService/OAIHarvester.php
index 978d489cf464d372effe1a33892e808914adb7d9..035dbac795ddb29449f485c5d68caa04798144fb 100644
--- a/library/Class/WebService/OAIHarvester.php
+++ b/library/Class/WebService/OAIHarvester.php
@@ -25,7 +25,7 @@ class Class_WebService_OAIHarvester {
 
   const
     PAGE_SEPARATOR = "\n--BOKEH_OAI_PAGE-----------------\n",
-    RESUMPTION_PATTERN = '|<resumptionToken[^>]*>([^<]*)\</resumptionToken>|',
+    RESUMPTION_PATTERN = '|<resumptionToken[^>]*>(<!\[CDATA\[)?([^<\]]*)(\]\]>)?\<\/resumptionToken>|',
     ERROR_PATTERN = '|<error code="([a-zA-Z]+)"[^>]*>|',
     DATE_PATTERN = '|^[0-9]{4}-[0-9]{2}-[0-9]{2}$|',
     IDENTIFIER_PATTERN = '|<identifier[^>]*>[^<]*</identifier>|',
@@ -138,7 +138,7 @@ class Class_WebService_OAIHarvester {
 
   protected function _parseToken($body) {
     return preg_match(static::RESUMPTION_PATTERN, $body, $matches)
-      ? $matches[1]
+      ? $matches[2]
       : null;
   }
 
diff --git a/tests/application/modules/opac/controllers/OAIControllerListIdentifiersTest.php b/tests/application/modules/opac/controllers/OAIControllerListIdentifiersTest.php
index e23b652caf05a775716550a7c698805d4f864aae..9f74b310c23edf2a35707ce5fc6080448939beb3 100644
--- a/tests/application/modules/opac/controllers/OAIControllerListIdentifiersTest.php
+++ b/tests/application/modules/opac/controllers/OAIControllerListIdentifiersTest.php
@@ -25,7 +25,8 @@ abstract class OAIControllerListIdentifiersTestCase
   protected
     $_xpath,
     $_xml,
-    $_catalog_loader;
+    $_catalog_loader,
+    $_sql;
 
 
   public function setUp() {
@@ -65,10 +66,22 @@ abstract class OAIControllerListIdentifiersTestCase
                     'created_at' => '2012-04-03',
                     'date_maj' => '2017-10-09 11:42:42']);
 
-    Zend_Registry::set('sql', $this->mock()->beStrict()
+    $this->_sql = $this->mock()->beStrict()
                        ->whenCalled('fetchAllByColumn')
-                       ->with('select notices.id_notice from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 0,5000')
-                       ->answers([2, 3, 4]));
+                       ->with('select notices.id_notice from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 0,100')
+                       ->answers([2, 3, 4]);
+
+    $this->_adaptMockSql();
+
+    Zend_Registry::set('sql', $this->_sql);
+  }
+
+
+  protected function _adaptMockSql(){
+    $this->_sql
+      ->whenCalled('fetchOne')
+      ->with('select count(*) from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1')
+      ->answers(3);
   }
 }
 
@@ -186,23 +199,74 @@ class OAIControllerListIdentifiersValidTest
 class OAIControllerListIdentifiersWithPaginatorTest
   extends OAIControllerListIdentifiersTestCase {
 
+  public function setUp() {
+    parent::setUp();
+    Class_WebService_OAI_Request_ListIdentifiers::$identifiers_by_page = 3;
+    $this->fixture(Class_Notice::class,
+                   ['id' => 1,
+                    'type_doc' => 1,
+                    'clef_alpha' => 'STARWARS1',
+                    'created_at' => '2001-12-14',
+                    'date_maj' => '2017-10-09 11:42:42',
+                    'titre_principal' => 'Star Wars']);
+    for($i=5; $i<=8; $i++)
+      $this->fixture(Class_Notice::class,
+                   ['id' => $i,
+                    'type_doc' => 1,
+                    'clef_alpha' => 'STARWARS'.$i,
+                    'created_at' => '2001-12-14',
+                    'date_maj' => '2017-10-09 11:42:42',
+                    'titre_principal' => 'Star Wars'.$i]);
+  }
+
+
+  public function tearDown(){
+    Class_WebService_OAI_Request_ListIdentifiers::$identifiers_by_page = 100;
+    parent::tearDown();
+  }
+
+
+  protected function _adaptMockSql(){
+    $this->_sql
+      ->whenCalled('fetchOne')
+      ->with('select count(*) from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1')
+      ->answers(8)
+      ->whenCalled('fetchAllByColumn')
+      ->with('select notices.id_notice from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 0,3')
+      ->answers([1, 2, 3])
+      ->whenCalled('fetchAllByColumn')
+      ->with('select notices.id_notice from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 4,3')
+      ->answers([4, 5, 6])
+      ->whenCalled('fetchAllByColumn')
+      ->with('select notices.id_notice from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 7,3')
+      ->answers([7, 8]);
+  }
+
 
   /** @test */
-  public function firstPageShouldHaveResumptionTokenToPage2() {
-    $this->dispatch('/opac/oai/request?verb=ListIdentifiers&metadataPrefix=oai_dc&set=zork&resumptionToken=oai_dc!zork!!!1');
+  public function pageCalledWithoutResumptionTokenShouldHaveResumptionTokenToPage2() {
+    $this->dispatch('/opac/oai/request?verb=ListIdentifiers&metadataPrefix=oai_dc&set=zork');
     $this->_xpath->assertXPathContentContains($this->_response->getBody(),
-                                              '//oai:resumptionToken',
+                                              '//oai:resumptionToken[@completeListSize="8"][@cursor="0"]',
                                               'oai_dc!zork!!!2');
   }
 
 
   /** @test */
-  public function secondPageShouldHaveResumptionTokenToPage3() {
+  public function pageCalledWithResumptionToken2ShouldHaveResumptionTokenToPage3() {
     $this->dispatch('/opac/oai/request?verb=ListIdentifiers&resumptionToken=oai_dc!zork!!!2');
     $this->_xpath->assertXPathContentContains($this->_response->getBody(),
-                                              '//oai:resumptionToken',
+                                              '//oai:resumptionToken[@completeListSize="8"][@cursor="3"]',
                                               'oai_dc!zork!!!3');
   }
+
+
+  /** @test */
+  public function pageCalledWithResumptionToken3ShouldNotHaveResumptionToken() {
+    $this->dispatch('/opac/oai/request?verb=ListIdentifiers&resumptionToken=oai_dc!zork!!!3');
+    $this->_xpath->assertNotXPath($this->_response->getBody(),
+                                  '//oai:resumptionToken');
+  }
 }
 
 
@@ -321,8 +385,11 @@ class OAIControllerListIdentifiersWithEmptySetTest
 
     Zend_Registry::get('sql')
       ->whenCalled('fetchAllByColumn')
-      ->with('select notices.id_notice from notices Where (created_at <= \'2012-01-01\' and MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 0,5000')
-      ->answers([]);
+      ->with('select notices.id_notice from notices Where (created_at <= \'2012-01-01\' and MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 0,100')
+      ->answers([])
+      ->whenCalled('fetchOne')
+      ->with('select count(*) from notices Where (created_at <= \'2012-01-01\' and MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1')
+      ->answers(0);
 
     $this->dispatch('/opac/oai/request?verb=ListIdentifiers&metadataPrefix=oai_dc&until=2012-01-01&set=zork');
     $this->_xml = $this->_response->getBody();
diff --git a/tests/application/modules/opac/controllers/OAIControllerListRecordsTest.php b/tests/application/modules/opac/controllers/OAIControllerListRecordsTest.php
index b6ad977ccee75e7e4e300814a071c59d2e6a124f..41bff3d761b76a7816460d002668533798157ee3 100644
--- a/tests/application/modules/opac/controllers/OAIControllerListRecordsTest.php
+++ b/tests/application/modules/opac/controllers/OAIControllerListRecordsTest.php
@@ -66,8 +66,11 @@ abstract class OAIControllerListRecordsInZorkSetTestCase
 
     Zend_Registry::set('sql', $this->mock()->beStrict()
                        ->whenCalled('fetchAllByColumn')
-                       ->with('select notices.id_notice from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 0,5000')
-                       ->answers([2,3,4]));
+                       ->with('select notices.id_notice from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 0,100')
+                       ->answers([2,3,4])
+                       ->whenCalled('fetchOne')
+                       ->with('select count(*) from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1')
+                       ->answers(3));
   }
 }
 
@@ -80,6 +83,7 @@ class OAIControllerListRecordsInZorkSetTest
 
   public function setUp() {
     parent::setUp();
+
     $this->dispatch('/opac/oai/request?verb=ListRecords&metadataPrefix=oai_dc&set=zork');
     $this->_body = $this->_response->getBody();
   }
@@ -287,8 +291,14 @@ class OAIControllerListRecordsInOaiDcBokehFormatTest
 
     Zend_Registry::set('sql', $this->mock()->beStrict()
                        ->whenCalled('fetchAllByColumn')
-                       ->with('select notices.id_notice from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 0,5000')
-                       ->answers([1]));
+                       ->with('select notices.id_notice from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 0,100')
+                       ->answers([1])
+                       ->whenCalled('fetchOne')
+                       ->with('select count(*) from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1')
+                       ->answers(1)
+                       ->whenCalled('fetchOne')
+                       ->with('select count(*) from notices Where (created_at <= \'2012-01-01\' and MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1')
+                       ->answers(1));
 
     $this->dispatch('/opac/oai/request?verb=ListRecords&metadataPrefix=oai_dc_bokeh&set=albums');
     $this->_body = $this->_response->getBody();
@@ -427,8 +437,11 @@ abstract class OAIControllerListRecordsIdentityProviderTest
 
     Zend_Registry::set('sql', $this->mock()->beStrict()
                        ->whenCalled('fetchAllByColumn')
-                       ->with('select notices.id_notice from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 0,5000')
-                       ->answers([1]));
+                       ->with('select notices.id_notice from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1 order by alpha_titre LIMIT 0,100')
+                       ->answers([1])
+                       ->whenCalled('fetchOne')
+                       ->with('select count(*) from notices Where (MATCH(facettes) AGAINST(\'+T1\' IN BOOLEAN MODE)) and type=1')
+                       ->answers(1));
   }
 }
 
diff --git a/tests/scenarios/Numel/hcc_oai_2.xml b/tests/scenarios/Numel/hcc_oai_2.xml
index c03b76746485e7d9c15a19bc2d9abe8e7f067505..88eea2d386151ce1ed609aa008f76aa2e331c1bd 100644
--- a/tests/scenarios/Numel/hcc_oai_2.xml
+++ b/tests/scenarios/Numel/hcc_oai_2.xml
@@ -2,6 +2,6 @@
 <responseDate>2022-05-25T09:36:52Z</responseDate>
 <request verb="ListRecords">bd.correze.fr/oaiserver.ashx</request>
 <ListRecords>
-<resumptionToken completeListSize="338426" cursor="338300">!!!338300!338426!oai_dc</resumptionToken>
+<resumptionToken completeListSize="338426" cursor="338300"><![CDATA[!!!338300!338426!oai_dc]]></resumptionToken>
 </ListRecords>
 </OAI-PMH>