Answers.Body: <p>Removing this from my site's nginx conf fixed it:</p>
  
  <pre><code>location ~* \.(?:manifest|appcache|html?|xml|json)$ {
   expires -1;
  }
  </code></pre>
  
  <p>However, what I really want to do is cache stuff, without breaking this endpoint</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-07-11T13:25:23.247Z
Answers.LastActivityDate: 2016-07-11T13:25:23.247Z
Answers.UserDisplayName: Adam Menczykowski
Answers.Body: <p>Updating the following line in our NGINX configuration also fixed the problem, this is similar to <code>expires -1</code>:</p>
  
  <p><b>From</b></p>
  
  <pre>
  # cache.appcache, your document html and data
  location ~* \.(?:manifest|appcache|html?|xml|json)$ {
    add_header Cache-Control "max-age=0";
  }
  </pre>
  
  <p><b>To</b></p>
  
  <pre>
  # cache.appcache, your document html and data
  location ~* \.(?:manifest|appcache|html?|xml)$ {
    add_header Cache-Control "max-age=0";
  }
  </pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-09-20T23:55:56.007Z
Answers.LastActivityDate: 2018-09-20T23:55:56.007Z
Answers.UserDisplayName: dillonbailey
Body: <p>The url: <a href="https://www.fira.co.uk/fullmembers.json" rel="nofollow">https://www.fira.co.uk/fullmembers.json</a></p>
  
  <p>is an endpoint for Craft's element API plugin.</p>
  
  <p>It has been working fine until recently I did a few things:</p>
  
  <ul>
  <li>I changed the site to https</li>
  <li>There have been some tweaks to the server config (nginx caching etc)</li>
  </ul>
  
  <p>The problem I am having is that the URL returns a 404 header but still displays the JSON response in the browser. This 404 is affecting my wget script that systematically saves the response to a static file, as to improve performance.</p>
  
  <p>Any ideas why the endpoint would be behaving like this?</p>
  
  <p>I haven't altered the elementapi.php recently but here it is:</p>
  
  <pre><code>&lt;?php
  namespace Craft;
  
  return [
      'endpoints' =&gt; [
          'fullmembers.json' =&gt; [
              'elementType' =&gt; 'User',
              'criteria' =&gt; ['group' =&gt; 'fullMembership', 'limit' =&gt; null, 'order' =&gt; 'companyName'],
              'paginate' =&gt; false,
              'transformer' =&gt; function(UserModel $member) {
                  // var_dump($member-&gt;memberAddress);
                  $businessCategories = [];
                  foreach ($member-&gt;businessTypeMarketSectorsProducts as $block) {
                      switch ($block-&gt;type-&gt;handle) {
                          case 'businessCategory':
  
                          $productValues = [];
                          foreach ($block-&gt;product as $prod) {
                              if ($prod-&gt;selected) {
                                  $productValues[] = $prod-&gt;value;
                              }
                          }
  
                          $businessCategories[] = [
                              'businessType' =&gt; $block-&gt;businessType-&gt;value,
                              'marketSector' =&gt; $block-&gt;marketSector-&gt;value,
                              'product' =&gt; $productValues
                          ];
  
                          break;
                      }
                  }
                  // $urlslug = strtolower(implode('-',explode(" ", $member-&gt;membersCompanyName)));
                  $urlslug = StringHelper::toKebabCase($member-&gt;membersCompanyName);
  
                  return [
                      'id' =&gt; $member-&gt;id,
                      'companyName' =&gt; $member-&gt;membersCompanyName,
                      // 'memberAddress' =&gt; $member-&gt;memberAddress-&gt;attributes,
                      'lat' =&gt; $member-&gt;memberAddress-&gt;lat,
                      'lng' =&gt; $member-&gt;memberAddress-&gt;lng,
                      'city' =&gt; $member-&gt;memberAddress-&gt;city,
                      'street1' =&gt; $member-&gt;memberAddress-&gt;street1,
                      'street2' =&gt; $member-&gt;memberAddress-&gt;street2,
                      'street3' =&gt; $member-&gt;membersAddressLine3,
                      'zip' =&gt; $member-&gt;memberAddress-&gt;zip,
                      'country' =&gt; $member-&gt;memberAddress-&gt;country,
                      'email' =&gt; $member-&gt;email,
                      'phone' =&gt; $member-&gt;membersPhoneNumber,
                      'profile' =&gt; UrlHelper::getUrl("directory/company/{$member-&gt;id}/{$urlslug}"),
                      'businessCategories' =&gt; $businessCategories
                  ];
              },
          ]
      ]
  ];
  </code></pre>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-07-09T04:40:23.693Z
Comments.Text: I think it's pretty unlikely that Craft or the ElementAPI plugin is adding the 404 header given that we haven't heard of any other issue like this and it started occurring after server config tweaks. I'd start checking your nginx.conf file or anything else that might be adding the header (Varnish? Cloudflare? Some proxy server?)
Comments.UserDisplayName: Brad Bell
Tags: <plugin-elementapi>
Title: Element API Endpoint returns data but has 404 header
ThreadText: # Element API Endpoint returns data but has 404 header
  
  (Asked by: username_0 on 2016-07-08)
  
  The url: <https://www.fira.co.uk/fullmembers.json>
  
  is an endpoint for Craft's element API plugin.
  
  It has been working fine until recently I did a few things:
  
  * I changed the site to https
  * There have been some tweaks to the server config (nginx caching etc)
  
  The problem I am having is that the URL returns a 404 header but still displays the JSON response in the browser. This 404 is affecting my wget script that systematically saves the response to a static file, as to improve performance.
  
  Any ideas why the endpoint would be behaving like this?
  
  I haven't altered the elementapi.php recently but here it is:
  
  ```
  <?php
  namespace Craft;
  
  return [
      'endpoints' => [
          'fullmembers.json' => [
              'elementType' => 'User',
              'criteria' => ['group' => 'fullMembership', 'limit' => null, 'order' => 'companyName'],
              'paginate' => false,
              'transformer' => function(UserModel $member) {
                  // var_dump($member->memberAddress);
                  $businessCategories = [];
                  foreach ($member->businessTypeMarketSectorsProducts as $block) {
                      switch ($block->type->handle) {
                          case 'businessCategory':
  
                          $productValues = [];
                          foreach ($block->product as $prod) {
                              if ($prod->selected) {
                                  $productValues[] = $prod->value;
                              }
                          }
  
                          $businessCategories[] = [
                              'businessType' => $block->businessType->value,
                              'marketSector' => $block->marketSector->value,
                              'product' => $productValues
                          ];
  
                          break;
                      }
                  }
                  // $urlslug = strtolower(implode('-',explode(" ", $member->membersCompanyName)));
                  $urlslug = StringHelper::toKebabCase($member->membersCompanyName);
  
                  return [
                      'id' => $member->id,
                      'companyName' => $member->membersCompanyName,
                      // 'memberAddress' => $member->memberAddress->attributes,
                      'lat' => $member->memberAddress->lat,
                      'lng' => $member->memberAddress->lng,
                      'city' => $member->memberAddress->city,
                      'street1' => $member->memberAddress->street1,
                      'street2' => $member->memberAddress->street2,
                      'street3' => $member->membersAddressLine3,
                      'zip' => $member->memberAddress->zip,
                      'country' => $member->memberAddress->country,
                      'email' => $member->email,
                      'phone' => $member->membersPhoneNumber,
                      'profile' => UrlHelper::getUrl("directory/company/{$member->id}/{$urlslug}"),
                      'businessCategories' => $businessCategories
                  ];
              },
          ]
      ]
  ];
  
  ```
  
  **Tags:** plugin-elementapi
  
  > **Comments:**
  > **username_1**: I think it's pretty unlikely that Craft or the ElementAPI plugin is adding the 404 header given that we haven't heard of any other issue like this and it started occurring after server config tweaks. I'd start checking your nginx.conf file or anything else that might be adding the header (Varnish? Cloudflare? Some proxy server?)  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2016-07-11. Score: 3 | Accepted answer
  
  Removing this from my site's nginx conf fixed it:
  
  ```
  location ~* \.(?:manifest|appcache|html?|xml|json)$ {
   expires -1;
  }
  
  ```
  
  However, what I really want to do is cache stuff, without breaking this endpoint
  
  
  ---
  
  ### Answer by username_2 on 2018-09-20. Score: 1
  
  Updating the following line in our NGINX configuration also fixed the problem, this is similar to `expires -1`:
  
  **From**
  
  ```
  
  # cache.appcache, your document html and data
  location ~* \.(?:manifest|appcache|html?|xml|json)$ {
    add_header Cache-Control "max-age=0";
  }
  
  ```
  
  **To**
  
  ```
  
  # cache.appcache, your document html and data
  location ~* \.(?:manifest|appcache|html?|xml)$ {
    add_header Cache-Control "max-age=0";
  }
  
  ```
  
  
  ---
  
  