<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Geoapify's tips and tutorials]]></title><description><![CDATA[Geoapify's tips and tutorials]]></description><link>https://geoapify.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Sat, 19 Sep 2026 15:37:23 GMT</lastBuildDate><atom:link href="https://geoapify.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to Geocode Tons of Addresses at Once]]></title><description><![CDATA[Geocoding is the process of converting addresses into their corresponding latitude and longitude coordinates.
If you started to read this post, chances are you also have hundreds, thousands, or even millions of postal addresses to process. So you alr...]]></description><link>https://geoapify.hashnode.dev/how-to-geocode-tons-of-addresses-at-once</link><guid isPermaLink="true">https://geoapify.hashnode.dev/how-to-geocode-tons-of-addresses-at-once</guid><category><![CDATA[Geospatial]]></category><category><![CDATA[SaaS]]></category><category><![CDATA[APIs]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[geolocation]]></category><dc:creator><![CDATA[Alfiya Tarasenko]]></dc:creator><pubDate>Mon, 27 Sep 2021 12:17:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1632733760202/z7N062CeQ.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Geocoding</strong> is the process of converting addresses into their corresponding latitude and longitude coordinates.</p>
<p>If you started to read this post, chances are you also have hundreds, thousands, or even millions of postal addresses to process. So you already have an idea of the difficulties and expenses of your task.</p>
<p>In this post, we would like to provide you a solution on how to geocode tons of addresses efficiently and at an affordable price with  <a target="_blank" href="https://www.geoapify.com/solutions/batch-geocoding-requests">Geoapify's Batch Geocoding API</a>.</p>
<h2 id="batch-geocoding-api-endpoint">Batch Geocoding API endpoint</h2>
<p>We, at  <a target="_blank" href="https://www.geoapify.com/">Geoapify</a>, created a <strong>Batch Geocoding</strong> endpoint to simplify and streamline the geocoding process of a large number of addresses. And since it works via <strong>HTTP Post</strong>, you can access it from any programming language or platform. </p>
<p>And here is how it's different from a Geocoding API call:</p>
<ul>
<li>Batch Geocoding <strong>accepts a list of addresses</strong> as an input while Geocoding processes only a single address;</li>
<li>Batch Geocoding has <strong>no rate limits</strong>, while even the most expensive plans of  Geocoding API limit you by the number of requests you can send in one second;</li>
<li>Batch Geocoding helps the provider to optimize server load and idle time better. So you can get <strong>better prices and conditions</strong>. For example, you get a 50% discount on address search with Geoapify Batch Geocoding.</li>
</ul>
<h2 id="call-batch-geocoder">Call Batch Geocoder</h2>
<p>All you need to do to create a geocoding job is send an HTTP Post request with addresses to the URL:</p>
<pre><code class="lang-url">https://api.geoapify.com/v1/batch/geocode/search?apiKey=YOUR_API_KEY
</code></pre>
<p>The addresses are accepted as a JSON array in the request body:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">var</span> data = [
    <span class="hljs-string">"668 Cedar St, San Carlos, CA 94070, United States of America"</span>,
    <span class="hljs-string">"545 Southwest Taylor Street, Portland, OR 97204, United States of America"</span>,
    <span class="hljs-string">"200 East 13th Street, Vancouver, WA 98660, United States of America"</span>,
];

<span class="hljs-comment">// Get an API Key on https://myprojects.geoapify.com</span>
<span class="hljs-keyword">var</span> url = <span class="hljs-string">"https://api.geoapify.com/v1/batch/geocode/search?apiKey=YOU_API_KEY"</span>;

fetch(url, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'post'</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">'Accept'</span>: <span class="hljs-string">'application/json'</span>,
      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>
    },
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify(data)
  })
  .then(getBodyAndStatus)
  .then(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (result.status !== <span class="hljs-number">202</span>) {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.reject(result)
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Job ID: "</span> + result.body.id);
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Job URL: "</span> + result.body.url)
    }
  })
  .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(err));

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getBodyAndStatus</span>(<span class="hljs-params">response</span>) </span>{
  <span class="hljs-keyword">return</span> response.json().then(<span class="hljs-function"><span class="hljs-params">responceBody</span> =&gt;</span> {
    <span class="hljs-keyword">return</span> {
      <span class="hljs-attr">status</span>: response.status,
      <span class="hljs-attr">body</span>: responceBody
    }
  });
}
</code></pre>
<p>You will get a job ID and URL for results as the response. Here is an example:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"65d9596895e5467f89584308b09bcf2b"</span>,
    <span class="hljs-attr">"status"</span>: <span class="hljs-string">"pending"</span>,
    <span class="hljs-attr">"url"</span>: <span class="hljs-string">"https://api.geoapify.com/v1/batch/geocode/search?id=65d9596895e5467f89584308b09bcf2b&amp;apiKey=YOUR_API_KEY"</span>
}
</code></pre>
<p>A batch geocoding job is scheduled on Geoapify's servers. Simply send an HTTP GET request on the results URL to pick up results.</p>
<h2 id="get-geocoding-results">Get Geocoding Results</h2>
<p>Of course, you can pick up results programmatically. You will need to implement an asynchronous call that checks if the job is completed and return results.</p>
<p>Here is a code sample to do that:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getAsyncResult</span>(<span class="hljs-params">url, timeout, maxAttempt</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      repeatUntilSuccess(resolve, reject, <span class="hljs-number">0</span>)
    }, timeout);
  });

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">repeatUntilSuccess</span>(<span class="hljs-params">resolve, reject, attempt</span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Attempt: "</span> + attempt);
    fetch(url)
      .then(getBodyAndStatus)
      .then(<span class="hljs-function"><span class="hljs-params">result</span> =&gt;</span> {
        <span class="hljs-keyword">if</span> (result.status === <span class="hljs-number">200</span>) {
          resolve(result.body);
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (attempt &gt;= maxAttempt) {
          reject(<span class="hljs-string">"Max amount of attempt achived"</span>);
        } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (result.status === <span class="hljs-number">202</span>) {
          <span class="hljs-comment">// Check again after timeout</span>
          <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
            repeatUntilSuccess(resolve, reject, attempt + <span class="hljs-number">1</span>)
          }, timeout);
        } <span class="hljs-keyword">else</span> {
          <span class="hljs-comment">// Something went wrong</span>
          reject(result.body)
        }
      })
      .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> reject(err));
  };
}
</code></pre>
<p>So now you can create a job and get the geocoding results:</p>
<pre><code class="lang-javascript">fetch(url, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'post'</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">'Accept'</span>: <span class="hljs-string">'application/json'</span>,
      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>
    },
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify(data)
  })
  .then(getBodyAndStatus)
  .then(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (result.status !== <span class="hljs-number">202</span>) {
      <span class="hljs-keyword">return</span> <span class="hljs-built_in">Promise</span>.reject(result)
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">return</span> getAsyncResult(result.body.url, <span class="hljs-number">1000</span>, <span class="hljs-number">100</span>).then(<span class="hljs-function"><span class="hljs-params">queryResult</span> =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(queryResult);
        <span class="hljs-keyword">return</span> queryResult;
      });
    }
  })
  .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(err));
</code></pre>
<p>We’ve developed a <a target="_blank" href="https://jsfiddle.net/Geoapify/zhce4opm/">JSFiddle</a> with the code samples provided. So you can test it and try the API by yourself.</p>
<p>Please note that the <code>getAsyncResult()</code> method has <strong>timeout</strong> parameters that define how often the API should check if the job is completed. </p>
<p>The processing time depends on the number of addresses. As the geocoding <strong>results are accessible within 24 hours</strong> after the job is completed, it doesn't make sense to set a small value when you geocode a large number of addresses. Roughly you can estimate the timeout as <code>numberOfAddresses/5</code>.</p>
<h2 id="geocode-addresses-with-no-code">Geocode Addresses with No Code</h2>
<p>The API works via an easy-to-use HTTP protocol, so <strong>you can call it with no coding</strong>. For example, you can use Postman to call the API. </p>
<p>Moreover, with the <strong>format=csv</strong> parameter you can get results in <strong>CSV format</strong> which can be inserted directly into an Excel or OpenOffice spreadsheet.</p>
<p>Here is a tutorial video demonstrating how to call the batch geocoder with an API testing platform:</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=-folu9K5ljc">https://www.youtube.com/watch?v=-folu9K5ljc</a></div>
<h2 id="conclusion">Conclusion</h2>
<p>Batch Geocoding is the way to go when you need to geocode a lot of addresses. It will save you time and money by processing all the addresses with a single job.</p>
<p><a target="_blank" href="https://www.geoapify.com/">Sign up</a> and try Geoapify's Batch Geocoding API! We offer developers-friendly APIs and <a target="_blank" href="https://www.geoapify.com/pricing/">prices affordable</a> for any business size. For example, with Geoapify's Batch Geocoder, you can lookup up to 6000 addresses/day for FREE!</p>
]]></content:encoded></item></channel></rss>