{"id":422,"date":"2016-04-08T15:37:55","date_gmt":"2016-04-08T15:37:55","guid":{"rendered":"http:\/\/zappysys.com\/blog\/?p=422"},"modified":"2026-03-19T23:09:47","modified_gmt":"2026-03-19T23:09:47","slug":"ssis-rest-api-looping-until-no-more-pages-found","status":"publish","type":"post","link":"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/","title":{"rendered":"How to do REST API Pagination in SSIS \/ ODBC Drivers"},"content":{"rendered":"<h2>Introduction<\/h2>\n<p>In our previous blog, we saw <a href=\"https:\/\/zappysys.com\/blog\/call-rest-api-using-ssis-web-service-task\/\">how to call REST in SSIS<\/a>\u00a0including concepts of Authentication \/ Error Handling. Now\u00a0in this post,\u00a0<strong>we will cover API Pagination.<\/strong> You will learn concepts and patterns about REST API Pagination (for JSON \/ XML \/ SOAP or CSV API).<\/p>\n<p>We will describe methods and steps to implement REST API Pagination in SSIS PowerPack or\u00a0\u00a0<a href=\"https:\/\/zappysys.com\/products\/odbc-powerpack\/\">ODBC PowerPack API Drivers (for apps like Excel, Power BI, Informatica&#8230;)<\/a> without coding. Both Products share a similar user interface with minor differences. For example purpose, we will show screenshots from SSIS PowerPack UI but concepts should remain same. You will also learn some techniques about <strong>how to implement an infinite loop in SSIS<\/strong>.\u00a0Sometimes your REST API requires you to loop through all pages until no more data found then you can use pattern described in this article (sample package attached at the end).<\/p>\n<p>In this article, we will use\u00a0<a href=\"https:\/\/zappysys.com\/products\/ssis-powerpack\/ssis-rest-api-web-service-task\/\">SSIS REST API Task<\/a> and <a href=\"\/\/zappysys.com\/products\/ssis-powerpack\/ssis-json-file-source\/\">JSON Source Connector<\/a>\u00a0to process data from RESTful web service. If you have to process XML (or SOAP) data from REST API then simply use <a href=\"\/\/zappysys.com\/products\/ssis-powerpack\/ssis-xml-source\/\">XML Source Connector for REST API, SOAP or File<\/a> rather than JSON Source.<\/p>\n<h2>Debugging REST API Requests<\/h2>\n<p>Before we look at various aspects of REST API Pagination, we highly recommend you install FREE Web Debugging Tool Fiddler. <a href=\"https:\/\/zappysys.com\/blog\/how-to-use-fiddler-to-analyze-http-web-requests\/\" target=\"_blank\" rel=\"noopener\">Look at this article<\/a> to understand how to debug REST API requests.<\/p>\n<h2>Method-1: REST API\u00a0Pagination\u00a0via URL Parameter<\/h2>\n<p>If you have paging requirement by specifying page number in URL then you can loop until no more pages found. Your REST API can indicate no more page found by any of the following ways.<\/p>\n<p><strong>Example URL:\u00a0<\/strong> http:\/\/myserver.com\/v1\/api\/getcustomers\/?<strong>page=1<\/strong><\/p>\n<p>If no more data found for specified page number then<\/p>\n<ol>\n<li>server may return an empty response<\/li>\n<li>server may return the response with specific error and response status code<\/li>\n<\/ol>\n<p><a href=\"\/\/zappysys.com\/products\/ssis-powerpack\/ssis-json-file-source\/\">JSON Source Connector<\/a>\u00a0comes with flexible paging options to handle this scenario. See below screenshot how to configure this.<\/p>\n<div id=\"attachment_10740\" style=\"width: 777px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10740\" class=\"size-full wp-image-10740\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode.png\" alt=\"Pagination Method 1 URL parameter mode\" width=\"767\" height=\"730\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode.png 767w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode-300x286.png 300w\" sizes=\"(max-width: 767px) 100vw, 767px\" \/><\/a><p id=\"caption-attachment-10740\" class=\"wp-caption-text\">REST API Looping\/Pagination via URL Page Number Parameter (Loop until last page detected)<\/p><\/div>\n<p><strong>URL with offset and limit<\/strong><\/p>\n<p>Sometimes you may have URLs with offset + limit parameters. as below. In this case, you can use the same technique as the above screenshot but just specify Page Num Indicator as <strong>offset<\/strong> and Increment by the same as your limit parameter (e.g. 1000 in this case). At runtime, your offset parameter will increment and generate URLs like below to fetch the next page.<\/p>\n<div class=\"su-note\"  style=\"border-color:#e5de9d;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\"><div class=\"su-note-inner su-u-clearfix su-u-trim\" style=\"background-color:#fff8b7;border-color:#ffffff;color:#333333;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\">If you don&#8217;t specify the offset parameter in the initial URL then <strong>offset=1<\/strong> will be assumed as the default start. If your offset starts at 0 then refer to the next section for a workaround (i.e. Use URL Path Mode with StartAt variable = 0). Also if your increment for offset is other than the default page size then you must include the limit \/ pagesize parameter in the URL as below (e.g. limit=100 which is rows per page)<\/div><\/div>\n<p><strong>Example URLs:\u00a0<\/strong><br \/>\nhttp:\/\/myserver.com\/v1\/api\/getcustomers\/?offset<strong>=1<\/strong>&amp;limit=1000<br \/>\nhttp:\/\/myserver.com\/v1\/api\/getcustomers\/?offset=<strong>1001<\/strong>&amp;limit=1000<br \/>\nhttp:\/\/myserver.com\/v1\/api\/getcustomers\/?offset=<strong>2001<\/strong>&amp;limit=1000<\/p>\n<h2>Method-2: REST API\u00a0Pagination\u00a0via URL Path<\/h2>\n<p>Sometimes your URL may contain a page or other identifier using path format.<\/p>\n<p><strong>Example URLs:\u00a0<\/strong><br \/>\nhttp:\/\/myserver.com\/v1\/api\/getcustomers\/<strong>1\/<\/strong><br \/>\nhttp:\/\/myserver.com\/v1\/api\/getcustomers\/<strong>2<\/strong>\/<br \/>\nhttp:\/\/myserver.com\/data\/file<strong>1<\/strong>.json<br \/>\nhttp:\/\/myserver.com\/data\/file<strong>2<\/strong>.json<\/p>\n<p>If no more data is found for the specified page number then<\/p>\n<ol>\n<li>the server may return a 404 error (page not found)<\/li>\n<li>server may return a response with a specific error and response status code<\/li>\n<\/ol>\n<p><a href=\"\/\/zappysys.com\/products\/ssis-powerpack\/ssis-json-file-source\/\">JSON Source Connector<\/a>\u00a0comes with flexible paging options to handle this scenario. See the below screenshot of how to configure this.<\/p>\n<div id=\"attachment_10741\" style=\"width: 785px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-2-JSON-source-Pagination-URL-path-mode-Page-number-offset-passed-as-URL-path.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10741\" class=\"size-full wp-image-10741\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-2-JSON-source-Pagination-URL-path-mode-Page-number-offset-passed-as-URL-path.png\" alt=\"Pagination Method 2 \" width=\"775\" height=\"479\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-2-JSON-source-Pagination-URL-path-mode-Page-number-offset-passed-as-URL-path.png 775w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-2-JSON-source-Pagination-URL-path-mode-Page-number-offset-passed-as-URL-path-300x185.png 300w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-2-JSON-source-Pagination-URL-path-mode-Page-number-offset-passed-as-URL-path-768x475.png 768w\" sizes=\"(max-width: 775px) 100vw, 775px\" \/><\/a><p id=\"caption-attachment-10741\" class=\"wp-caption-text\">REST API Looping\/Pagination via URL Path (Loop until last page detected)<\/p><\/div>\n<h3>URL with Skip Parameter (Offset starts at zero)<\/h3>\n<p>Now let&#8217;s look at another common pattern just like the offset we discussed earlier but in the Skip pattern, it starts at zero rather than offset=1. In the previous mode, we didn&#8217;t have the option to supply the initial value to start the counter but if you use Path mode then you can start the counter at some custom value. See the below screen to show how we can setup pagination with the skip method with custom increment.<\/p>\n<div class=\"su-note\"  style=\"border-color:#e5de9d;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\"><div class=\"su-note-inner su-u-clearfix su-u-trim\" style=\"background-color:#fff8b7;border-color:#ffffff;color:#333333;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;\">If your increment for offset is other than the default page size then you must include page size parameter in the URL as below (e.g. pagesize=100 which is rows per page. Some APIs name this parameter in different way e.g. count=1000 or limit=100. Refer to the API documentation to know exact names)<\/div><\/div>\n<p><strong>Example URLs<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">http:\/\/mysite.com\/api\/getorders?skip=0&amp;pagesize=100\r\nhttp:\/\/mysite.com\/api\/getorders?skip=100&pagesize=100\r\nhttp:\/\/mysite.com\/api\/getorders?skip=200&pagesize=100\r\nhttp:\/\/mysite.com\/api\/getorders?skip=300&pagesize=100\r\n....<\/pre>\n<div id=\"attachment_10742\" style=\"width: 1098px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-2-Pagination-URL-with-Skip-Parameter.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10742\" class=\"size-full wp-image-10742\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-2-Pagination-URL-with-Skip-Parameter.png\" alt=\"Pagination method 2 URL with Skip Parameter\" width=\"1088\" height=\"481\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-2-Pagination-URL-with-Skip-Parameter.png 1088w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-2-Pagination-URL-with-Skip-Parameter-300x133.png 300w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-2-Pagination-URL-with-Skip-Parameter-768x340.png 768w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-2-Pagination-URL-with-Skip-Parameter-1024x453.png 1024w\" sizes=\"(max-width: 1088px) 100vw, 1088px\" \/><\/a><p id=\"caption-attachment-10742\" class=\"wp-caption-text\">REST API Pagination with Custom Skip \/ Increment Settings (Offset Starts from 0)<\/p><\/div>\n<p>&nbsp;<\/p>\n<h2>Method-3 : REST API\u00a0Pagination\u00a0via Response Attribute (Next Link or Cursor)<\/h2>\n<p>This method is not discussed in this article but <a href=\"https:\/\/zappysys.com\/blog\/odata-paging-rest-api-paging-using-ssis-json-source\/\" target=\"_blank\" rel=\"noopener\">click here to read more<\/a><\/p>\n<p>There are mainly 3 ways you can get next link or cursor.<\/p>\n<ol>\n<li>Full Link (e.g. nextPage : &#8220;https:\/\/mysite.com\/api\/v1\/1\/?filter=AAAA&#8221; )<\/li>\n<li>Partial Link\u00a0\u00a0(e.g. nextPage : &#8220;\/api\/v1\/getcustomer\/1\/?filter=AAAA&#8221; )<\/li>\n<li>Cursor Continuation Token (e.g.\u00a0\u00a0 nextCursor : &#8220;xxxxAAAbbbbCccc112233==&#8221; )<\/li>\n<\/ol>\n<h3>Next Link Method\u00a0(Partial or Full URL)<\/h3>\n<p>Example response with next URL would be<\/p>\n<pre class=\"lang:default highlight:0 decode:true \">{ \r\n  \"value\" : [....], \r\n  \"odata.nextLink\" : \"http:\/\/abc.com\/customers\/2\/\" \r\n}<\/pre>\n<p>In this method you don&#8217;t specify page number in URL. If response\u00a0include many records then you will get partial response along with indicator\u00a0of next link.<\/p>\n<p>For more information about this\u00a0<em>REST API Pagination<\/em>\u00a0please check below links. It explains in depth how to paginate REST API response with next page link found in response.<\/p>\n<p><a title=\"Permalink to OData Paging using SSIS \u2013 REST API Paging Example\" href=\"\/\/zappysys.com\/blog\/odata-paging-rest-api-paging-using-ssis-json-source\/\" rel=\"bookmark\">OData Paging using SSIS \u2013 REST API Paging Example<\/a><\/p>\n<p><a title=\"Permalink to Read Twitter data in SSIS using REST API Task and JSON Source \u2013 OAuth2 Protocol\" href=\"\/\/zappysys.com\/blog\/read-twitter-data-in-ssis-using-rest-api-task-json-source-oauth2\/#Handling_paging_of_large_REST_API_result_set_with_twitter_data_8211_loopingcursoring\" rel=\"bookmark\">Read Twitter data in SSIS using REST API Task and JSON Source \u2013 OAuth2 Protocol<\/a><\/p>\n<div id=\"attachment_10743\" style=\"width: 706px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-3-Pagination-via-Response-Attribute-Next-Link-or-Cursor.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10743\" class=\"size-full wp-image-10743\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-3-Pagination-via-Response-Attribute-Next-Link-or-Cursor.png\" alt=\"Method-3: Next Link Method (Partial or Full URL)\" width=\"696\" height=\"557\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-3-Pagination-via-Response-Attribute-Next-Link-or-Cursor.png 696w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-3-Pagination-via-Response-Attribute-Next-Link-or-Cursor-300x240.png 300w\" sizes=\"(max-width: 696px) 100vw, 696px\" \/><\/a><p id=\"caption-attachment-10743\" class=\"wp-caption-text\">SSIS API Pagination \u2013 Next Link from Response Attribute<\/p><\/div>\n<h3>Next Link &#8211; Detect the last page based on empty rows (Regular Expression)<\/h3>\n<p>Now let&#8217;s look at a little bit different scenario where the Next Link is never empty even on the last page. This can cause an infinite loop if we configure it like the last section. So in such a case (see below example) when the last page still has the next link URL but the data row array is empty then use settings like the screenshot below.<\/p>\n<p><strong>First Page Example<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">{ \r\n  \"value\" : [....], \r\n  \"odata.nextLink\" : \"http:\/\/abc.com\/customers\/2\/\" \r\n}<\/pre>\n<p><strong>Last Page\u00a0Example<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">{ \r\n  \"value\" : [], \r\n  \"odata.nextLink\" : \"http:\/\/abc.com\/customers\/NNNN\/\" \r\n}<\/pre>\n<p><strong>Example: Last Page<\/strong><\/p>\n<p>Basically, configure the following options<\/p>\n<ul>\n<li>Set <b>Stop indicator attribute<\/b> to the same node which contains data rows (without array brackets). E.g. <strong>$.items<\/strong><\/li>\n<li>Set <b>Stop indicator value \/ Regular Expression\u00a0<\/b>to something like <span class=\"lang:default highlight:0 decode:true crayon-inline \">[]<\/span>\u00a0 assuming the last page has the same way. <a href=\"https:\/\/zappysys.com\/blog\/how-to-use-fiddler-to-analyze-http-web-requests\/\" target=\"_blank\" rel=\"noopener\">Check Fiddler Trace<\/a> for exact text on the last page.<\/li>\n<\/ul>\n<div id=\"attachment_10744\" style=\"width: 678px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-3-Pagination-Detect-the-last-page-based-on-empty-rows.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10744\" class=\"size-full wp-image-10744\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-3-Pagination-Detect-the-last-page-based-on-empty-rows.png\" alt=\"Method-3 Detect the last page based on empty rows \" width=\"668\" height=\"399\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-3-Pagination-Detect-the-last-page-based-on-empty-rows.png 668w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-3-Pagination-Detect-the-last-page-based-on-empty-rows-300x179.png 300w\" sizes=\"(max-width: 668px) 100vw, 668px\" \/><\/a><p id=\"caption-attachment-10744\" class=\"wp-caption-text\">Last Page with non empty next link and empty data array (Detect Last Page based on zero row count)<\/p><\/div>\n<h3>Cursor\u00a0Method<\/h3>\n<p>Many API returns cursor rather than link. Cursor method usually used to support a large number of records. Cursor is opened at server side with initial query information you submit and if cursor has more records you may get next cursor indicator in your response. In cursor method you have to supply Suffix for Next URL so after First URL your next URL will contain extra attribute which will include pagination information.<\/p>\n<p><strong>Suffix for next URL<\/strong><\/p>\n<p>Suffix for next URL can include special placeholders. There are two placeholders allowed. If you wish to append Next URL value in raw text then use <strong>&lt;%nextlink%&gt;<\/strong> but if your API needs value in\u00a0encoded format e.g. A%20B rather than A+B then you have to use <strong>&lt;%nextlink_encoded%&gt;<\/strong><\/p>\n<p><strong>Example URLs for Cursor:<\/strong><\/p>\n<p>Below is few sample URLs in the log when pagination occurs via Cursor method. As you see the first URL has Cursor=* means its first call, after first request server may send next cursor in the response body (see example)<\/p>\n<pre>{ \r\n\u00a0 data: [....], \r\n\u00a0 nextCursor: \"Aooo\/MxxxxxxxxxxxtdA==\" \r\n}<\/pre>\n<p>First URL: http:\/\/api.crossref.org\/members\/311\/works?filter=type:journal-article&amp;rows=100&amp;cursor=*<br \/>\nSecond\u00a0URL: http:\/\/api.crossref.org\/members\/311\/works?filter=type:journal-article&amp;rows=100&amp;cursor=Aooo\/MxxxxxxxxxxxtdA==<br \/>\nThird\u00a0URL: http:\/\/api.crossref.org\/members\/311\/works?filter=type:journal-article&amp;rows=100&amp;cursor=Booo\/MxxxxxxxxxxxtdA==<br \/>\n&#8230;..<br \/>\n&#8230;..<\/p>\n<h2>Method-4: Pass Page Number in Body Attribute<\/h2>\n<p>Some API allows you to pass your PageSize and Page number inside Request Body (i.e. POST data) in that case you may configure your options like below (We used Google AdWords Api as an example)<\/p>\n<div id=\"attachment_10745\" style=\"width: 838px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-4-pagination.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10745\" class=\"size-full wp-image-10745\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-4-pagination.png\" alt=\"Method-4 Pass Page Number in Body Attribute\" width=\"828\" height=\"735\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-4-pagination.png 828w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-4-pagination-300x266.png 300w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-4-pagination-768x682.png 768w\" sizes=\"(max-width: 828px) 100vw, 828px\" \/><\/a><p id=\"caption-attachment-10745\" class=\"wp-caption-text\">Configure REST API Pagination \u2013 using Page Number via POST Body Method<\/p><\/div>\n<div id=\"attachment_10746\" style=\"width: 838px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-4-Settings.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10746\" class=\"size-full wp-image-10746\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-4-Settings.png\" alt=\"Method-4: Pass Page Number in Body Attribute example\" width=\"828\" height=\"735\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-4-Settings.png 828w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-4-Settings-300x266.png 300w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-4-Settings-768x682.png 768w\" sizes=\"(max-width: 828px) 100vw, 828px\" \/><\/a><p id=\"caption-attachment-10746\" class=\"wp-caption-text\">REST API Pagination \u2013 Passing PageNumber inside POST Body (Example: Google AdWords SOAP API)<\/p><\/div>\n<h2>Method-5: REST API\u00a0Pagination\u00a0via multiple URL parameters (e.g. Start and End)<\/h2>\n<p>In the previous section, you saw how to pass page numbers via URL (Single Parameter: http:\/\/abc.com\/?page=1). However, sometimes you have a pagination requirement where you have to specify multiple parameters that need increment. See below example URL.<\/p>\n<pre class=\"lang:default highlight:0 decode:true\">http:\/\/abc.com\/?startRow=1&amp;endRow=100\r\nhttp:\/\/abc.com\/?startRow=101&endRow=200\r\nhttp:\/\/abc.com\/?startRow=201&endRow=300\r\n...<\/pre>\n<div id=\"attachment_10747\" style=\"width: 838px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-5-pagination.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10747\" class=\"size-full wp-image-10747\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-5-pagination.png\" alt=\"Method-5: REST API Pagination via multiple URL parameters (e.g. Start and End)\" width=\"828\" height=\"478\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-5-pagination.png 828w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-5-pagination-300x173.png 300w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-5-pagination-768x443.png 768w\" sizes=\"(max-width: 828px) 100vw, 828px\" \/><\/a><p id=\"caption-attachment-10747\" class=\"wp-caption-text\">Pagination via Multiple URL Parameters<\/p><\/div>\n<h2>Method-6: REST API\u00a0Pagination\u00a0via Header (Next Link in Header)<\/h2>\n<p>Another popular pagination method is paginate via Header. In this method, each API response includes special Header which indicates next link for your response. In header method there are two approaches. [1] Custom Method [2] RFC 5988 Method. Lets look at both.<\/p>\n<h3>Next Link in Custom Header<\/h3>\n<p>In this method you have to specify which response header contains next URL. When no more NEXT url found in response reader stops.<\/p>\n<div id=\"attachment_10749\" style=\"width: 650px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-REST-API-Pagination-via-Header.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10749\" class=\"size-full wp-image-10749\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-REST-API-Pagination-via-Header.png\" alt=\"Method 6 REST API Pagination via Headers\" width=\"640\" height=\"213\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-REST-API-Pagination-via-Header.png 640w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-REST-API-Pagination-via-Header-300x100.png 300w\" sizes=\"(max-width: 640px) 100vw, 640px\" \/><\/a><p id=\"caption-attachment-10749\" class=\"wp-caption-text\">Custom Header Pagination Method<\/p><\/div>\n<h3>Next Link in Header as per RFC 5988<\/h3>\n<p>In this method, HTTP response contains a\u00a0special header (Link) which contains next link for our response. If no link found to read more data then reader stops. This method is described well here in <a href=\"https:\/\/tools.ietf.org\/html\/rfc5988\" target=\"_blank\" rel=\"noopener\">RFC 5988<\/a>. Check this <a href=\"https:\/\/developer.github.com\/v3\/guides\/traversing-with-pagination\/\" target=\"_blank\" rel=\"noopener\">GitHub API Example<\/a> to understand more on this pagination method.<\/p>\n<div id=\"attachment_10751\" style=\"width: 696px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Next-Link-in-Header-as-per-RFC-5988.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10751\" class=\"size-full wp-image-10751\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Next-Link-in-Header-as-per-RFC-5988.png\" alt=\"Method 6 Next Link in Header as per RFC 5988\" width=\"686\" height=\"144\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Next-Link-in-Header-as-per-RFC-5988.png 686w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Next-Link-in-Header-as-per-RFC-5988-300x63.png 300w\" sizes=\"(max-width: 686px) 100vw, 686px\" \/><\/a><p id=\"caption-attachment-10751\" class=\"wp-caption-text\">Link Header Pagination Method (RFC 5988)<\/p><\/div>\n<h2>Method-7: REST API\u00a0Pagination using Cursor \/ Continuation Token from Response Header<\/h2>\n<p>There will be a time when your API sends some sort of Continuation Token in Response Header and you have to use that token to call next request. Some API needs this token passed as query string in Next URL and in some API you have to pass as request header. We will cover both cases in the following section.<\/p>\n<p>Your API might call these tokens as &#8220;Cursor&#8221; too so we will use these both terms in the following section (They both mean same thing).<\/p>\n<p>There are few ways these APIs pass Cursor to the next request<\/p>\n<ol>\n<li>Pass Cursor via Request Header with <strong>same header name<\/strong><\/li>\n<li>Pass Cursor via Request Header with <strong>different header name (introduced in v4.2.3)<\/strong><\/li>\n<li>Pass multiple Response Headers via Request Headers (Azure DocumentDB style usecase)<\/li>\n<li>Pass Cursor via URL Query String Parameter (<strong>introduced in v3.0 or later<\/strong>)<\/li>\n<\/ol>\n<p>Lets see all approaches.<\/p>\n<h3>Pass Token via Request Header (Same header name)<\/h3>\n<p>Consider the API pagination use case in which you get some sort of continuation token in the response header and you take it and pass in the next request via request header (same header name).<\/p>\n<p>Example:<\/p>\n<p><strong>First Request \/ Response:<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">------- Request ------\r\nGET https:\/\/abc.com\/api\/getdata\r\n\r\n------- Response ------\r\nx-token: Nxdfabcd11111\r\n\r\n{ some response data }<\/pre>\n<p><strong>Second Request \/ Response:<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">------- Request ------\r\nGET https:\/\/abc.com\/api\/getdata\r\nx-token: Nxdfabcd11111\r\n\r\n------- Response ------\r\nx-token: Nxdfabcd22222\r\n\r\n{ some response data }<\/pre>\n<p>&#8230;&#8230;<\/p>\n<p>&#8230;&#8230;<\/p>\n<p><strong>Last Request \/ Response:<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">------- Request ------\r\nGET https:\/\/abc.com\/api\/getdata\r\nx-token: Nxdfabcd22222\r\n\r\n------- Response ------\r\n\r\n{ some response data }<\/pre>\n<p>For above pagination pattern\u00a0 that just enter the response header name in <strong>Page Num Indicator<\/strong> field as below<\/p>\n<div id=\"attachment_10752\" style=\"width: 697px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Pass-Token-via-Request-Header.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10752\" class=\"size-full wp-image-10752\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Pass-Token-via-Request-Header.png\" alt=\"Method 7 Pass Token via Request Header\" width=\"687\" height=\"126\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Pass-Token-via-Request-Header.png 687w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Pass-Token-via-Request-Header-300x55.png 300w\" sizes=\"(max-width: 687px) 100vw, 687px\" \/><\/a><p id=\"caption-attachment-10752\" class=\"wp-caption-text\">Pagination using response header continuation token \u2013 Pass as Request Header<\/p><\/div>\n<p>All possible formats for Page Num Indicator is below<\/p>\n<p>x-page-token<br \/>\nx-token1, x-token2<br \/>\nRequestUrlQueryName=ResponseHeaderName<br \/>\nheader::RequestHeaderName=ResponseHeaderName<br \/>\nRequestUrlQueryName=ResponseHeaderName(regular-expression)<\/p>\n<h3>Pass Token via Request Header (Different header name)<\/h3>\n<p>Consider the API pagination use case just like previous one but only different is request header name is not same as response header name. For example rather than x-token in request we need to call it x-next-token.<\/p>\n<p>Example:<\/p>\n<p><strong>First Request \/ Response:<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">------- Request ------\r\nGET https:\/\/abc.com\/api\/getdata\r\n\r\n------- Response ------\r\nx-token: Nxdfabcd11111\r\n\r\n{ some response data }<\/pre>\n<p><strong>Second Request \/ Response:<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">------- Request ------\r\nGET https:\/\/abc.com\/api\/getdata\r\nx-next-token: Nxdfabcd11111\r\n\r\n------- Response ------\r\nx-token: Nxdfabcd22222\r\n\r\n{ some response data }<\/pre>\n<p>&#8230;&#8230;<\/p>\n<p>&#8230;&#8230;<\/p>\n<p><strong>Last Request \/ Response:<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">------- Request ------\r\nGET https:\/\/abc.com\/api\/getdata\r\nx-next-token: Nxdfabcd22222\r\n\r\n------- Response ------\r\n\r\n{ some response data }<\/pre>\n<p>For above pagination pattern\u00a0 that just enter the response header name in <strong>Page Num Indicator<\/strong> field as below<\/p>\n<div id=\"attachment_10753\" style=\"width: 702px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Pass-Token-via-Request-Header.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10753\" class=\"size-full wp-image-10753\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Pass-Token-via-Request-Header.png\" alt=\"Method 7 Pass Token via Request Header \" width=\"692\" height=\"197\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Pass-Token-via-Request-Header.png 692w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Pass-Token-via-Request-Header-300x85.png 300w\" sizes=\"(max-width: 692px) 100vw, 692px\" \/><\/a><p id=\"caption-attachment-10753\" class=\"wp-caption-text\">Pagination using response header continuation token \u2013 Pass as Request Header (Different name)<\/p><\/div>\n<h3>Pass multiple Response Headers via Request Headers (Azure DocumentDB style usecase)<\/h3>\n<p>Some API like <a href=\"https:\/\/docs.microsoft.com\/en-us\/rest\/api\/cosmos-db\/list-documents\" target=\"_blank\" rel=\"noopener\">Azure Cosmos DB<\/a> uses Continuation Token via Header approach. In that case you can enter single header name or multiple headers like below (For multiple headers use comma)<\/p>\n<div id=\"attachment_10754\" style=\"width: 687px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Pass-multiple-Response-Headers-via-Request-Headers-Azure-DocumentDB-style-usecase.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10754\" class=\"size-full wp-image-10754\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Pass-multiple-Response-Headers-via-Request-Headers-Azure-DocumentDB-style-usecase.png\" alt=\"Method 7 Pass multiple Response Headers via Request Headers\" width=\"677\" height=\"207\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Pass-multiple-Response-Headers-via-Request-Headers-Azure-DocumentDB-style-usecase.png 677w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Pass-multiple-Response-Headers-via-Request-Headers-Azure-DocumentDB-style-usecase-300x92.png 300w\" sizes=\"(max-width: 677px) 100vw, 677px\" \/><\/a><p id=\"caption-attachment-10754\" class=\"wp-caption-text\">REST API Pagination using Continuation Token via Header (Azure CosmosDB \/ DocumentDB API Example )<\/p><\/div>\n<p>You can use use tools <a href=\"https:\/\/zappysys.com\/blog\/how-to-use-fiddler-to-analyze-http-web-requests\/\" target=\"_blank\" rel=\"noopener\">like Fiddler<\/a> to see paginated requests as below.<\/p>\n<p><strong>First Request<\/strong><\/p>\n<div id=\"attachment_10755\" style=\"width: 953px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Fiddler-1.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10755\" class=\"size-full wp-image-10755\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Fiddler-1.png\" alt=\"Method 7 fiddler example 1\" width=\"943\" height=\"777\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Fiddler-1.png 943w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Fiddler-1-300x247.png 300w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Fiddler-1-768x633.png 768w\" sizes=\"(max-width: 943px) 100vw, 943px\" \/><\/a><p id=\"caption-attachment-10755\" class=\"wp-caption-text\">View Paginated Requests in Fiddler (Azure CosmosDB API Example)<\/p><\/div>\n<p><strong>Second Request<\/strong><\/p>\n<div id=\"attachment_10756\" style=\"width: 1044px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Fiddler-2.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10756\" class=\"size-full wp-image-10756\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Fiddler-2.png\" alt=\"Method 7 fiddler reuqest 2 \" width=\"1034\" height=\"785\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Fiddler-2.png 1034w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Fiddler-2-300x228.png 300w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Fiddler-2-768x583.png 768w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-Fiddler-2-1024x777.png 1024w\" sizes=\"(max-width: 1034px) 100vw, 1034px\" \/><\/a><p id=\"caption-attachment-10756\" class=\"wp-caption-text\">Pass Next Page Token via Header (View Paginated Requests in Fiddler \u2013 Azure CosmosDB API Example)<\/p><\/div>\n<h3>Pass Token via URL Parameter (Query String)<\/h3>\n<p>In the new version we added a feature where you can actually read Continuation Token (i.e. Cursor) from Response Header and then pass to next request in the URL rather than Request Header. Here is the <a href=\"https:\/\/api.rosnet.com\/#tag\/Checks\" target=\"_blank\" rel=\"noopener\">example API<\/a> which uses such method.<\/p>\n<p><strong>First Request<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">--------- Request ---------\r\nGET\r\nhttp:\/\/test.com\/api\/getdata\r\n\r\n--------- Response ---------\r\nX-RESPONSE-TOKEN : Pg2xxxxxxxxxxxxxxxxx\r\n\r\n{ data : [ 1,2,3.... 10 ] }\r\n<\/pre>\n<p><strong>Second Request\u00a0<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">--------- Request ---------\r\nGET\r\nhttp:\/\/test.com\/api\/getdata?cursor=Pg2xxxxxxxxxxxxxxxxx\r\n\r\n--------- Response ---------\r\nX-RESPONSE-TOKEN : Pg3xxxxxxxxxxxxxxxxx\r\n\r\n{ data : [ 11,12,13.... 20 ] }<\/pre>\n<p>Here is how to configure above pagination pattern<\/p>\n<div id=\"attachment_10759\" style=\"width: 706px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Pass-Token-via-URL-Parameter.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10759\" class=\"size-full wp-image-10759\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Pass-Token-via-URL-Parameter.png\" alt=\"Method 7 Pass Token via URL Parameter (Query String)\" width=\"696\" height=\"148\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Pass-Token-via-URL-Parameter.png 696w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-6-Pass-Token-via-URL-Parameter-300x64.png 300w\" sizes=\"(max-width: 696px) 100vw, 696px\" \/><\/a><p id=\"caption-attachment-10759\" class=\"wp-caption-text\">Pass Response Header value to URL (Cursor)<\/p><\/div>\n<h3>Pass Token via URL Parameter (Query String) &#8211; with\u00a0custom Regular expression (Usecase: Salesforce BULK query API)<\/h3>\n<p>Now consider previous scenario but with slightly different requirement. By default previous pagination pattern stops when specified response header is missing or response header value is blank. However is some cases header value contains custom string to indicate last page. For example x-token: NULL. In such case we need to use <strong>Page Num Indicator<\/strong> like below (must use v4.2.3 or higher in SSIS PowerPack \/ 1.5.2 or higher in ODBC PowerPack)<\/p>\n<pre class=\"lang:default highlight:0 decode:true\">nextUrlParameterName=responseHeadername(Some_Regular_Expression)<\/pre>\n<p>For example to stop pagination in below case you have to enter Page Num Indicator as below. It says stop pagination when\u00a0 &#8220;NULL&#8221; word is detected<\/p>\n<pre class=\"lang:default highlight:0 decode:true \">cursor=X-RESPONSE-TOKEN(^((?!NULL\\b).)*$)<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>First Request<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">--------- Request ---------\r\nGET\r\nhttp:\/\/test.com\/api\/getdata\r\n\r\n--------- Response ---------\r\nX-RESPONSE-TOKEN : Pg2xxxxxxxxxxxxxxxxx\r\n\r\n{ data : [ 1,2,3.... 10 ] }\r\n<\/pre>\n<p><strong>Second Request\u00a0<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">--------- Request ---------\r\nGET\r\nhttp:\/\/test.com\/api\/getdata?cursor=Pg2xxxxxxxxxxxxxxxxx\r\n\r\n--------- Response ---------\r\nX-RESPONSE-TOKEN : Pg3xxxxxxxxxxxxxxxxx\r\n\r\n{ data : [ 11,12,13.... 20 ] }<\/pre>\n<p>&#8230;&#8230;<\/p>\n<p>&#8230;&#8230;<\/p>\n<p><strong>Last Request\u00a0<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">--------- Request ---------\r\nGET\r\nhttp:\/\/test.com\/api\/getdata?cursor=Pg3xxxxxxxxxxxxxxxxx\r\n\r\n--------- Response ---------\r\nX-RESPONSE-TOKEN : NULL\r\n\r\n{ data : [ 21,22,23.... 30 ] }<\/pre>\n<p>Here is how to configure above pagination pattern<\/p>\n<div id=\"attachment_10761\" style=\"width: 706px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-with-custom-Regular-expression.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10761\" class=\"size-full wp-image-10761\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-with-custom-Regular-expression.png\" alt=\"Method 7 with custom Regular expression\" width=\"696\" height=\"156\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-with-custom-Regular-expression.png 696w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-7-with-custom-Regular-expression-300x67.png 300w\" sizes=\"(max-width: 696px) 100vw, 696px\" \/><\/a><p id=\"caption-attachment-10761\" class=\"wp-caption-text\">Pass Response Header value to URL (Cursor)<\/p><\/div>\n<h2>Method-8: Pass Pagination Token in Request Body<\/h2>\n<p>In previous section (Method-4: Pass Page Number in Body Attribute ) we saw how to pass simple numeric page counter in Body. This is fine for some API but if your API has base64 style text token then counter based method doesn&#8217;t work. Also if you have requirement to hide page attribute node in first request and send page counter node in second request body (Changing Request Body Pattern for First vs Next)\u00a0 then check next two sections.<\/p>\n<p>Next two sections covers two API Pagination patterns to fetch 100 rows (1000 in each page) . Both requires to send token in Body but second section is more complex need (Different Body Attributes in first vs next requests )<\/p>\n<h3>Passing Page Token in Body (Blank Token in first request allowed)<\/h3>\n<p>Lets look at simple pattern where first request has blank token in Body but all other requests until we find last page we keep sending non-empty token. This approach works as long as API Provider doesn&#8217;t mind having Blank Token in first request. If you get error then check next section to handle more complex way.<\/p>\n<p>Here is the example of API which needs token in body<\/p>\n<p><strong>First API call<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">--------- Request ---------\r\nPOST http:\/\/test.com\/api\/getdata\r\n\r\n{ searchFor: \"Account\", continueToken:\"\" }\r\n\r\n--------- Response ---------\r\n{recordsFound: 5000, data: [\"Acct1\", \"Acct2\"..., \"Acct1000\"], nextToken:\"AxBxCx112233001==\" }<\/pre>\n<p><strong>Second API call<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">--------- Request ---------\r\nPOST http:\/\/test.com\/api\/getdata\r\n\r\n{ searchFor: \"Account\", continueToken:\"AxBxCx112233001==\" }\r\n\r\n--------- Response ---------\r\n{data: [\"Acct1001\", \"Acct1002\"..., \"Acct2000\"], nextToken:\"AxBxCx112233002==\" }<\/pre>\n<p>&#8230;.. many more calls &#8230;<\/p>\n<p>&#8230;. many more calls &#8230;.<\/p>\n<p><strong>Last API call (no more\u00a0nextToken in response so STOP pagination)<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">--------- Request ---------\r\nPOST http:\/\/test.com\/api\/getdata\r\n\r\n{ searchFor: \"Account\", continueToken:\"AxBxCx112233009==\" }\r\n\r\n--------- Response ---------\r\n{data: [\"Acct9001\", \"Acct9002\"..., \"Acct10000\"] }<\/pre>\n<p>So if you have such pattern then you can set few properties<\/p>\n<p>For such issue you can use Changing few properties like below. Use Property Grid if you cant find on UI<\/p>\n<ul>\n<li>Set EnablePageTokenForBody\u00a0 = <span class=\"lang:default decode:true crayon-inline \">True<\/span><\/li>\n<li>Set PagePlaceholders = <span class=\"lang:default decode:true crayon-inline\">header=|;filter=|;<\/span><\/li>\n<li>Set HttpRequestData =\u00a0<span class=\"lang:default highlight:0 decode:true crayon-inline\">{\u00a0searchFor: &#8220;Account&#8221;, continueToken:&#8221;[$pagetoken$]&#8221; }<\/span><\/li>\n<\/ul>\n<div id=\"attachment_10762\" style=\"width: 838px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Pass-Passing-Page-Token-in-Body-1.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10762\" class=\"size-full wp-image-10762\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Pass-Passing-Page-Token-in-Body-1.png\" alt=\"Method 8 Pass Passing Page Token in Body 1\" width=\"828\" height=\"488\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Pass-Passing-Page-Token-in-Body-1.png 828w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Pass-Passing-Page-Token-in-Body-1-300x177.png 300w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Pass-Passing-Page-Token-in-Body-1-768x453.png 768w\" sizes=\"(max-width: 828px) 100vw, 828px\" \/><\/a><p id=\"caption-attachment-10762\" class=\"wp-caption-text\">Setting Body with [$pagetoken$] to implement dynamic pagination<\/p><\/div>\n<div id=\"attachment_10763\" style=\"width: 838px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Pass-Passing-Page-Token-in-Body-2.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10763\" class=\"size-full wp-image-10763\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Pass-Passing-Page-Token-in-Body-2.png\" alt=\"Method 8 advanced pagination tab\" width=\"828\" height=\"437\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Pass-Passing-Page-Token-in-Body-2.png 828w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Pass-Passing-Page-Token-in-Body-2-300x158.png 300w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Pass-Passing-Page-Token-in-Body-2-768x405.png 768w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Pass-Passing-Page-Token-in-Body-2-720x380.png 720w\" sizes=\"(max-width: 828px) 100vw, 828px\" \/><\/a><p id=\"caption-attachment-10763\" class=\"wp-caption-text\">Setting Page Placeholders in Advanced Pagination tab.<\/p><\/div>\n<h3>Passing Page Token in Body (Blank Token in first request)<\/h3>\n<p>Now let&#8217;s look at more complex pattern. Here our first request body is different than other requests.<\/p>\n<p><strong>First API call<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">--------- Request ---------\r\nPOST http:\/\/test.com\/api\/getdata\r\n\r\n{ searchFor: \"Account\" }\r\n\r\n--------- Response ---------\r\n{recordsFound: 5000, data: [\"Acct1\", \"Acct2\"..., \"Acct1000\"], nextToken:\"AxBxCx112233001==\" }<\/pre>\n<p><strong>Second API call<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">--------- Request ---------\r\nPOST http:\/\/test.com\/api\/getdataNext\r\n\r\n{ continueToken:\"AxBxCx112233001==\" }\r\n\r\n--------- Response ---------\r\n{data: [\"Acct1001\", \"Acct1002\"..., \"Acct2000\"], nextToken:\"AxBxCx112233002==\" }<\/pre>\n<p>&#8230;.. many more calls &#8230;<\/p>\n<p>&#8230;. many more calls &#8230;.<\/p>\n<p><strong>Last API call (no more\u00a0nextToken)<\/strong><\/p>\n<pre class=\"lang:default highlight:0 decode:true\">--------- Request ---------\r\nPOST http:\/\/test.com\/api\/getdataNext\r\n\r\n{ continueToken:\"AxBxCx112233009==\" }\r\n\r\n--------- Response ---------\r\n{data: [\"Acct9001\", \"Acct9002\"..., \"Acct10000\"] }<\/pre>\n<p>So notice few things<\/p>\n<ul>\n<li>First Request Body \/ URL is different than second \/ third and Nth API call<\/li>\n<li>For first request we do not have token attribute but after first request we do have token attribute<\/li>\n<\/ul>\n<p>We have <a href=\"https:\/\/zappysys.com\/blog\/call-amazon-mws-api-using-ssis-marketplace-web-service\/\" target=\"_blank\" rel=\"noopener\">this article<\/a> and <a href=\"https:\/\/zappysys.com\/blog\/read-data-netsuite-ssis-simpletalk-soap-api\/\" target=\"_blank\" rel=\"noopener\">this article<\/a> which describes similar pattern.<\/p>\n<p>Now lets look at how to solve both problems<\/p>\n<h3>Passing PageToken or Counter in Next API Call Body<\/h3>\n<p>For such issue you can use Changing few properties like below. Use Property Grid if you cant find on UI<\/p>\n<ul>\n<li>Set EnablePageTokenForBody\u00a0 = <span class=\"lang:default decode:true crayon-inline \">True<\/span><\/li>\n<li>Set PagePlaceholders = <span class=\"lang:default decode:true crayon-inline\">header=|;filter=|;<\/span><\/li>\n<li>Set HttpRequestData =\u00a0<span class=\"lang:default highlight:0 decode:true crayon-inline\">[$tag$]<\/span><\/li>\n<li>Set HasDifferentNextPageInfo =\u00a0<span class=\"lang:default decode:true crayon-inline \">True<\/span><\/li>\n<li>Set FirstPageBodyPart =\u00a0<span class=\"lang:default highlight:0 decode:true crayon-inline\">{\u00a0searchFor: &#8220;Account&#8221;}<\/span><\/li>\n<li>Set NextPageBodyPart =\u00a0<span class=\"lang:default highlight:0 decode:true crayon-inline\">{\u00a0token:&#8221;[$pagetoken$]&#8221; }<\/span><\/li>\n<\/ul>\n<p>So notice how we defined Body in two different properies as template. And in HttpRequestData we used <span class=\"lang:default decode:true crayon-inline \">[$tag$]<\/span><\/p>\n<h2>Output Page Number as column<\/h2>\n<p>Sometimes you have use case where you want to Start Page Number from the last page loaded successfully. By default, you will see one additional column __FileName in the output. This column contains PageNumber \u00a0from URL for each row. You can save this into database so when next time you run your SSIS you can start at MAX(PageNumber) + 1.<\/p>\n<p>Outputting PageNumber option is not visible by default so Use Property Grid and look for <strong>OutputFileName<\/strong> property (Default=true)<\/p>\n<h2>Last Page Detection<\/h2>\n<p>Every API may have different way of telling you that you reached last page or no more data found so you should stop looping. SSIS PowerPack comes with many options so you can implement desired logic for last page detection.<\/p>\n<p>Following approaches supported by last page detection. Below options are not applicable if you are using Method#3 (Response contains Next Link \/ Cursor)<\/p>\n<ol>\n<li>Detect the\u00a0last page by row count<\/li>\n<li>Detect the\u00a0last page by response status code<\/li>\n<li>Detect the\u00a0last page by error message (substring search)<\/li>\n<li>Detect the\u00a0last page by response size<\/li>\n<li>Detect the last page based on response value or regular expression pattern<\/li>\n<\/ol>\n<p>Now lets look at each setting. You should choose correct one based on your API behavior<\/p>\n<h3>Detect the last page by row count<\/h3>\n<p>If your API returns blank document or blank Array (if its JSON) then you can use this method to detect the last page. So when no content found in Response document it will stop pagination.<\/p>\n<p>See below example of JSON API .. It shows sample first page and Sample last page (Assuming you entered Filter as $.Records[*] to extract data from Records array.<\/p>\n<p><strong>First Page<\/strong><\/p>\n<pre>{\u00a0\r\n\u00a0 Records : [ {...}, {...}, {...} .........\u00a0]\r\n}<\/pre>\n<p><strong>Last Page<\/strong><\/p>\n<pre class=\"\">{\u00a0\r\n\u00a0 Records : [\u00a0\u00a0]\r\n}<\/pre>\n<div id=\"attachment_10769\" style=\"width: 654px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-row-count.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10769\" class=\"size-full wp-image-10769\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-row-count.png\" alt=\"Method 8 Detect the last page by row count\" width=\"644\" height=\"222\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-row-count.png 644w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-row-count-300x103.png 300w\" sizes=\"(max-width: 644px) 100vw, 644px\" \/><\/a><p id=\"caption-attachment-10769\" class=\"wp-caption-text\">SSIS API Pagination \u2013 Detect the last page by row count (Blank document or array)<\/p><\/div>\n<h3>Detect the last page by response status code<\/h3>\n<p>Sometimes you get error with status code when the last page is reached (Most common is 404). So rather than failure, you can treat that status code as last page indicator using this option (see below).<\/p>\n<div id=\"attachment_10766\" style=\"width: 644px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-response-status-code.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10766\" class=\"size-full wp-image-10766\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-response-status-code.png\" alt=\"Method 8 Detect the last page by response status code\" width=\"634\" height=\"245\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-response-status-code.png 634w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-response-status-code-300x116.png 300w\" sizes=\"(max-width: 634px) 100vw, 634px\" \/><\/a><p id=\"caption-attachment-10766\" class=\"wp-caption-text\">SSIS API Pagination \u2013 Detect last page by response status code<\/p><\/div>\n<h3>Detect the last page by the error message<\/h3>\n<p>If you cant use above two methods and want to detect the last page based on a certain error string in the response then use below approach.<\/p>\n<div id=\"attachment_10767\" style=\"width: 647px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-the-error-message.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10767\" class=\"size-full wp-image-10767\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-the-error-message.png\" alt=\"Method 8 Detect the last page by the error message\" width=\"637\" height=\"249\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-the-error-message.png 637w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-the-error-message-300x117.png 300w\" sizes=\"(max-width: 637px) 100vw, 637px\" \/><\/a><p id=\"caption-attachment-10767\" class=\"wp-caption-text\">SSIS API Pagination \u2013 Detect the last page by error\/response string search<\/p><\/div>\n<h3>Detect the last page by response size<\/h3>\n<p>Sometimes you can detect the last page by response size. For example, your response contains &#8220;&#8211;&#8221; only if no more data is found then you cannot use any of the above approaches and you have to detect based on response size (e.g. less than 3 bytes). See below<\/p>\n<div id=\"attachment_10768\" style=\"width: 654px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-response-size-1.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10768\" class=\"size-full wp-image-10768\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-response-size-1.png\" alt=\"Method 8 Detect the last page by response size\" width=\"644\" height=\"243\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-response-size-1.png 644w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-by-response-size-1-300x113.png 300w\" sizes=\"(max-width: 644px) 100vw, 644px\" \/><\/a><p id=\"caption-attachment-10768\" class=\"wp-caption-text\">SSIS API Pagination \u2013 Detect last page by response size<\/p><\/div>\n<h3>Detect the last page based on the response attribute value<\/h3>\n<p>There will be a time when you want to detect the last page based on some indicator value from your response. In that case, you can use the following settings to detect the last page.<\/p>\n<ul>\n<li>Select Paging mode =Response Attribute Mode<\/li>\n<li>Select Next Link Attribute (Example:\u00a0<strong>$.next_page<\/strong> )<\/li>\n<li>Select Stop Indicator Attribute (Example:\u00a0<strong>$.hasMorePages<\/strong> )<\/li>\n<li>Enter a value for Stop Indicator (Example:\u00a0<strong>false<\/strong> )<\/li>\n<\/ul>\n<p>If you don&#8217;t want to use Hardcoded value for stop indicator and want to use expression then see next section.<\/p>\n<h3>Detect the last page based on regular expression pattern<\/h3>\n<p>There will be a time when you want to detect the last page based on some indicator value from your response. In that case, you can use the following settings to detect the last page.<\/p>\n<ul>\n<li>Select Paging mode =Response Attribute Mode<\/li>\n<li>Select Next Link Attribute (Example:\u00a0<strong>$.next_page<\/strong> )<\/li>\n<li>Select Stop Indicator Attribute (Example:\u00a0<strong>$.count<\/strong> )<\/li>\n<li>Enter regex pattern (regular expression) for Stop Indicator (Example:\u00a0<strong>regex=^\\d{1,3}$<\/strong>\u00a0). Stop when count attribute is less than 1000 in other word less than 4 digits.<\/li>\n<\/ul>\n<p>Here is an example from <a href=\"https:\/\/zappysys.com\/blog\/read-zendesk-data-in-ssis-call-rest-api\/\" target=\"_blank\" rel=\"noopener\">Zendesk API<\/a> (Stop pagination when count attribute from the response is less than 1000)<\/p>\n<div id=\"attachment_10770\" style=\"width: 687px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-based-on-regular-expression-pattern.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10770\" class=\"size-full wp-image-10770\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-based-on-regular-expression-pattern.png\" alt=\"Method 8 Detect the last page based on regular expression pattern\" width=\"677\" height=\"418\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-based-on-regular-expression-pattern.png 677w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-8-Detect-the-last-page-based-on-regular-expression-pattern-300x185.png 300w\" sizes=\"(max-width: 677px) 100vw, 677px\" \/><\/a><p id=\"caption-attachment-10770\" class=\"wp-caption-text\">Pagination for Zendesk Incremental API \u2013 Next Link and Last Page detection using Stop Indicator Regular Expression<\/p><\/div>\n<div class=\"content_block\" id=\"custom_post_widget-9862\"><h2>Handling API Rate Limit - Retry on too many API requests<\/h2>\r\n<p>Many API restricts you from calling too many API calls too soon (just to save their servers from being overwhelmed) - <a href=\"https:\/\/shopify.dev\/api\/usage\/rate-limits\" target=\"_blank\" rel=\"noopener\">Example<\/a>. Let's think this way if you fetching a million rows via paginated response and the very last page fails then you won't be happy because now you have to fetch everything again. To solve this ZappySys provides retry options on HTTP \/ OAuth and REST API connection managers.<\/p>\r\n\r\n<p>Generally, when you exceed the rate limit, the server sends you <strong>error code 429<\/strong> but it can be something else too or multiple codes are returned. In the below example, we use 503. Check your API documentation to know the exact code you should retry.<\/p>\r\n\r\n<p>To set the retry options go to connection settings (e.g. HTTP \/ OAuth \/ REST connection). The below example is for OAuth connection.<\/p>\r\n\r\n<p>To retry on multiple codes use Pipe as a delimiter.\u00a0Example: <strong>429|503<\/strong><\/p>\r\n\r\n\r\n<div class=\"wp-caption alignnone\">\r\n <a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2018\/09\/http-retry-settings-oauth-connection.png\">\r\n   <img decoding=\"async\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2018\/09\/http-retry-settings-oauth-connection.png\" alt=\"Retry Settings for API Rate Limit Exceeded Error (Status code 429)\" \/>\r\n <\/a>\r\n<p class=\"wp-caption-text\">Retry Settings for API Rate Limit Exceeded Error (Status code 429 or other)<\/p>\r\n<\/div><\/div>\n<h2>Performance Tips<\/h2>\n<p>You can improve performance of your API calls by doing a few changes (again not every API may support this)<\/p>\n<ul>\n<li>Use the maximum page size possible (e.g. if you doing pagination you can set max possible page size &#8211; refer to your API documentation whats the default size and what is the max page size you can supply)<br \/>\ne.g.\u00a0 \/myapi?pagesize=100\u00a0 (parameter name can be something else like limit=100)<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h2>SSIS Infinite Loop<\/h2>\n<p>So now you know how to paginate automatically in <a href=\"\/\/zappysys.com\/products\/ssis-powerpack\/ssis-json-file-source\/\">JSON Source Connector<\/a> but what if you want to use <a href=\"https:\/\/zappysys.com\/products\/ssis-powerpack\/ssis-rest-api-web-service-task\/\">REST API Task<\/a> for pagination? Some custom scenarios like web scraping require you to download all HTML\u00a0pages until no more results found?\u00a0In that case, you most likely need infinite looping pattern (Loop until the last page detected). To loop through pages until the last page is reached you can perform the following logic.<\/p>\n<p>The last page can be detected based on any of the following ways<br \/>\n1. Check Response StatusCode<br \/>\n2. Check Error Message<br \/>\n3. Check Response Size (If less than X bytes then consider as the last page)<\/p>\n<p>REST API Task support #1 and #2 scenarios. If you want to check bytes then use the expression in Expression Task or Script Task<br \/>\n(e.g. @exitloop = LEN(@responseData) &lt;= 3 )<\/p>\n<p><b>URL for Rest API Task (On Request Settings Tab)<\/b><br \/>\nWhen you configure REST API Task enter URL as below so its dynamic. You can use PageCounter variable anywhere in the URL.<\/p>\n<pre>\/\/zappysys.com\/downloads\/files\/test\/cust-{{User::pagecounter}}.json<\/pre>\n<div id=\"attachment_10771\" style=\"width: 755px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/SSIS-Infinite-Loop-1.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10771\" class=\"size-full wp-image-10771\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/SSIS-Infinite-Loop-1.png\" alt=\"SSIS Infinite Loop part 1 \" width=\"745\" height=\"957\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/SSIS-Infinite-Loop-1.png 745w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/SSIS-Infinite-Loop-1-234x300.png 234w\" sizes=\"(max-width: 745px) 100vw, 745px\" \/><\/a><p id=\"caption-attachment-10771\" class=\"wp-caption-text\">SSIS REST API Looping \u2013 Pass Page number in URL, SSIS Infinite Loop<\/p><\/div>\n<div id=\"attachment_10772\" style=\"width: 729px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/SSIS-Infinite-Loop-2.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-10772\" class=\"size-full wp-image-10772\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/SSIS-Infinite-Loop-2.png\" alt=\"SSIS Infinite Loop part 2\" width=\"719\" height=\"504\" srcset=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/SSIS-Infinite-Loop-2.png 719w, https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/SSIS-Infinite-Loop-2-300x210.png 300w\" sizes=\"(max-width: 719px) 100vw, 719px\" \/><\/a><p id=\"caption-attachment-10772\" class=\"wp-caption-text\">Configure For Loop Task for Infinite Looping (Loop until last page found)<\/p><\/div>\n<h2>Download Sample SSIS Package<\/h2>\n<p><a href=\"\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/SSIS-Loop-Rest-API-2012.dtsx.zip\">SSIS-Loop-Rest-API-2012.dtsx (Zip file)<\/a><\/p>\n<h2>Video Tutorial &#8211; Reading data from API in SSIS<\/h2>\n<p>In case you missed our previous article about <a href=\"https:\/\/zappysys.com\/blog\/call-rest-api-using-ssis-web-service-task\/\" target=\"_blank\" rel=\"noopener\">calling REST API is SSIS<\/a> then check below video.<\/p>\n<div class=\"lyte-wrapper fourthree\" style=\"width:480px;max-width:100%;margin:5px auto;\"><div class=\"lyMe\" id=\"WYL_aO8cVRyCBWw\"><div id=\"lyte_aO8cVRyCBWw\" data-src=\"https:\/\/zappysys.com\/blog\/wp-content\/plugins\/wp-youtube-lyte\/lyteCache.php?origThumbUrl=%2F%2Fi.ytimg.com%2Fvi%2FaO8cVRyCBWw%2Fhqdefault.jpg\" class=\"pL\"><div class=\"tC\"><div class=\"tT\"><\/div><\/div><div class=\"play\"><\/div><div class=\"ctrl\"><div class=\"Lctrl\"><\/div><div class=\"Rctrl\"><\/div><\/div><\/div><noscript><a href=\"https:\/\/youtu.be\/aO8cVRyCBWw\" rel=\"nofollow\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/zappysys.com\/blog\/wp-content\/plugins\/wp-youtube-lyte\/lyteCache.php?origThumbUrl=https%3A%2F%2Fi.ytimg.com%2Fvi%2FaO8cVRyCBWw%2F0.jpg\" alt=\"\" width=\"480\" height=\"340\" \/><br \/>Watch this video on YouTube<\/a><\/noscript><\/div><\/div><div class=\"lL\" style=\"max-width:100%;width:480px;margin:5px auto;\"><\/div><\/p>\n<p>&nbsp;<\/p>\n<h2>Conclusion<\/h2>\n<p>It can be time consuming and steep learning curve to write C#\/JAVA code to handle your rest api integration but using some Tasks and Connectors listed below can help you to solve big headache and provide clean drag and drop REST API integration in SSIS for virtually any REST API Source (e.g. Twitter, Facebook, Salesforce, office 365). <a href=\"\/\/zappysys.com\/products\/ssis-powerpack\/\">Download SSIS PowerPack<\/a> and try it out by yourself.<\/p>\n<h2 class=\"su-box-title\">SSIS Components\u00a0for REST API\/JSON\/XML\/SOAP<\/h2>\n<div class=\"su-box-content su-clearfix\">\n<table>\n<tbody>\n<tr>\n<td width=\"36\"><img decoding=\"async\" src=\"\/\/zappysys.com\/images\/ssis-powerpack\/SSIS-Json-Source-Adapter.png\" alt=\"Custom SSIS Components - JSON Source (File and REST API Connector)\" width=\"32\" \/><\/td>\n<td><a href=\"\/\/zappysys.com\/products\/ssis-powerpack\/ssis-json-file-source\/\" target=\"_blank\" rel=\"noopener\"><span style=\"color: #248cc8;\">JSON Source Connector (File, REST API)<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td width=\"36\"><span style=\"color: #248cc8;\"><img decoding=\"async\" src=\"\/\/zappysys.com\/images\/ssis-powerpack\/ssis-export-json-file-task.png\" alt=\"Custom SSIS Tasks - Export JSON File Task\" width=\"32\" \/><\/span><\/td>\n<td><a href=\"\/\/zappysys.com\/products\/ssis-powerpack\/ssis-export-json-file-task\/\" target=\"_blank\" rel=\"noopener\"><span style=\"color: #248cc8;\">Export JSON File Task<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td width=\"36\"><span style=\"color: #248cc8;\"><img decoding=\"async\" src=\"\/\/zappysys.com\/images\/ssis-powerpack\/ssis-json-parser-task.png\" alt=\"Custom SSIS Tasks - JSON Parser Task\" width=\"32\" \/><\/span><\/td>\n<td><a href=\"\/\/zappysys.com\/products\/ssis-powerpack\/ssis-json-parser-task-free\/\" target=\"_blank\" rel=\"noopener\"><span style=\"color: #248cc8;\">JSON Parser Task<\/span><\/a><\/td>\n<\/tr>\n<tr>\n<td width=\"36\"><span style=\"color: #248cc8;\"><img decoding=\"async\" src=\"\/\/zappysys.com\/images\/ssis-powerpack\/ssis-xml-source.png\" alt=\"Custom SSIS Tasks - XML Source Connector (File, SOAP, REST API)\" width=\"32\" \/><\/span><\/td>\n<td><a href=\"\/\/zappysys.com\/products\/ssis-powerpack\/ssis-xml-source\/\" target=\"_blank\" rel=\"noopener\"><span style=\"color: #248cc8;\">XML Source Connector (File, SOAP, REST API)<\/span><\/a><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In our previous blog, we saw how to call REST in SSIS\u00a0including concepts of Authentication \/ Error Handling. Now\u00a0in this post,\u00a0we will cover API Pagination. You will learn concepts and patterns about REST API Pagination (for JSON \/ XML \/ SOAP or CSV API). We will describe methods and steps to implement REST API [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":10740,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16,17,8,62],"tags":[232,13,24,160,27,161,3,12,100],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\r\n<title>How to do REST API Pagination in SSIS \/ ODBC Drivers | ZappySys Blog<\/title>\r\n<meta name=\"description\" content=\"Learn concepts of REST API Pagination in SSIS (5 different ways). Use JSON Source or XML Source to loop through many requests in few clicks.\" \/>\r\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\r\n<link rel=\"canonical\" href=\"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/\" \/>\r\n<meta property=\"og:locale\" content=\"en_US\" \/>\r\n<meta property=\"og:type\" content=\"article\" \/>\r\n<meta property=\"og:title\" content=\"How to do REST API Pagination in SSIS \/ ODBC Drivers | ZappySys Blog\" \/>\r\n<meta property=\"og:description\" content=\"Learn concepts of REST API Pagination in SSIS (5 different ways). Use JSON Source or XML Source to loop through many requests in few clicks.\" \/>\r\n<meta property=\"og:url\" content=\"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/\" \/>\r\n<meta property=\"og:site_name\" content=\"ZappySys Blog\" \/>\r\n<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/ZappySys\/\" \/>\r\n<meta property=\"article:published_time\" content=\"2016-04-08T15:37:55+00:00\" \/>\r\n<meta property=\"article:modified_time\" content=\"2026-03-19T23:09:47+00:00\" \/>\r\n<meta property=\"og:image\" content=\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode.png\" \/>\r\n\t<meta property=\"og:image:width\" content=\"767\" \/>\r\n\t<meta property=\"og:image:height\" content=\"730\" \/>\r\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\r\n<meta name=\"author\" content=\"ZappySys\" \/>\r\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\r\n<meta name=\"twitter:creator\" content=\"@https:\/\/twitter.com\/zappysys\/\" \/>\r\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"ZappySys\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"23 minutes\" \/>\r\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/\",\"url\":\"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/\",\"name\":\"How to do REST API Pagination in SSIS \/ ODBC Drivers | ZappySys Blog\",\"isPartOf\":{\"@id\":\"https:\/\/zappysys.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode.png\",\"datePublished\":\"2016-04-08T15:37:55+00:00\",\"dateModified\":\"2026-03-19T23:09:47+00:00\",\"author\":{\"@id\":\"https:\/\/zappysys.com\/blog\/#\/schema\/person\/2756c237457fbc95d82cb38962f81f82\"},\"description\":\"Learn concepts of REST API Pagination in SSIS (5 different ways). Use JSON Source or XML Source to loop through many requests in few clicks.\",\"breadcrumb\":{\"@id\":\"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/#primaryimage\",\"url\":\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode.png\",\"contentUrl\":\"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode.png\",\"width\":767,\"height\":730,\"caption\":\"REST API Looping\/Pagination via URL Page Number Parameter (Loop until last page detected)\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/zappysys.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to do REST API Pagination in SSIS \/ ODBC Drivers\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/zappysys.com\/blog\/#website\",\"url\":\"https:\/\/zappysys.com\/blog\/\",\"name\":\"ZappySys Blog\",\"description\":\"SSIS \/ ODBC Drivers \/ API Connectors for JSON, XML, Azure, Amazon AWS, Salesforce, MongoDB and more\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/zappysys.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/zappysys.com\/blog\/#\/schema\/person\/2756c237457fbc95d82cb38962f81f82\",\"name\":\"ZappySys\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/zappysys.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5c9be148088ba9b8af8e955c5f7c22b5?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5c9be148088ba9b8af8e955c5f7c22b5?s=96&d=mm&r=g\",\"caption\":\"ZappySys\"},\"sameAs\":[\"http:\/\/www.zappysys.com\/\",\"https:\/\/www.facebook.com\/ZappySys\/\",\"https:\/\/twitter.com\/https:\/\/twitter.com\/zappysys\/\"],\"url\":\"https:\/\/zappysys.com\/blog\/author\/admin\/\"}]}<\/script>\r\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to do REST API Pagination in SSIS \/ ODBC Drivers | ZappySys Blog","description":"Learn concepts of REST API Pagination in SSIS (5 different ways). Use JSON Source or XML Source to loop through many requests in few clicks.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/","og_locale":"en_US","og_type":"article","og_title":"How to do REST API Pagination in SSIS \/ ODBC Drivers | ZappySys Blog","og_description":"Learn concepts of REST API Pagination in SSIS (5 different ways). Use JSON Source or XML Source to loop through many requests in few clicks.","og_url":"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/","og_site_name":"ZappySys Blog","article_author":"https:\/\/www.facebook.com\/ZappySys\/","article_published_time":"2016-04-08T15:37:55+00:00","article_modified_time":"2026-03-19T23:09:47+00:00","og_image":[{"width":767,"height":730,"url":"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode.png","type":"image\/png"}],"author":"ZappySys","twitter_card":"summary_large_image","twitter_creator":"@https:\/\/twitter.com\/zappysys\/","twitter_misc":{"Written by":"ZappySys","Est. reading time":"23 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/","url":"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/","name":"How to do REST API Pagination in SSIS \/ ODBC Drivers | ZappySys Blog","isPartOf":{"@id":"https:\/\/zappysys.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/#primaryimage"},"image":{"@id":"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/#primaryimage"},"thumbnailUrl":"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode.png","datePublished":"2016-04-08T15:37:55+00:00","dateModified":"2026-03-19T23:09:47+00:00","author":{"@id":"https:\/\/zappysys.com\/blog\/#\/schema\/person\/2756c237457fbc95d82cb38962f81f82"},"description":"Learn concepts of REST API Pagination in SSIS (5 different ways). Use JSON Source or XML Source to loop through many requests in few clicks.","breadcrumb":{"@id":"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/#primaryimage","url":"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode.png","contentUrl":"https:\/\/zappysys.com\/blog\/wp-content\/uploads\/2016\/04\/Method-1-JSON-source-Pagination-URL-parameter-mode.png","width":767,"height":730,"caption":"REST API Looping\/Pagination via URL Page Number Parameter (Loop until last page detected)"},{"@type":"BreadcrumbList","@id":"https:\/\/zappysys.com\/blog\/ssis-rest-api-looping-until-no-more-pages-found\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zappysys.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to do REST API Pagination in SSIS \/ ODBC Drivers"}]},{"@type":"WebSite","@id":"https:\/\/zappysys.com\/blog\/#website","url":"https:\/\/zappysys.com\/blog\/","name":"ZappySys Blog","description":"SSIS \/ ODBC Drivers \/ API Connectors for JSON, XML, Azure, Amazon AWS, Salesforce, MongoDB and more","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zappysys.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/zappysys.com\/blog\/#\/schema\/person\/2756c237457fbc95d82cb38962f81f82","name":"ZappySys","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zappysys.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5c9be148088ba9b8af8e955c5f7c22b5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5c9be148088ba9b8af8e955c5f7c22b5?s=96&d=mm&r=g","caption":"ZappySys"},"sameAs":["http:\/\/www.zappysys.com\/","https:\/\/www.facebook.com\/ZappySys\/","https:\/\/twitter.com\/https:\/\/twitter.com\/zappysys\/"],"url":"https:\/\/zappysys.com\/blog\/author\/admin\/"}]}},"_links":{"self":[{"href":"https:\/\/zappysys.com\/blog\/wp-json\/wp\/v2\/posts\/422"}],"collection":[{"href":"https:\/\/zappysys.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zappysys.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zappysys.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zappysys.com\/blog\/wp-json\/wp\/v2\/comments?post=422"}],"version-history":[{"count":38,"href":"https:\/\/zappysys.com\/blog\/wp-json\/wp\/v2\/posts\/422\/revisions"}],"predecessor-version":[{"id":10773,"href":"https:\/\/zappysys.com\/blog\/wp-json\/wp\/v2\/posts\/422\/revisions\/10773"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/zappysys.com\/blog\/wp-json\/wp\/v2\/media\/10740"}],"wp:attachment":[{"href":"https:\/\/zappysys.com\/blog\/wp-json\/wp\/v2\/media?parent=422"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zappysys.com\/blog\/wp-json\/wp\/v2\/categories?post=422"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zappysys.com\/blog\/wp-json\/wp\/v2\/tags?post=422"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}