Answers.Body: <p>In case anyone finds this in a Google search, this is how you'd do it in Craft 3, if, say, you wanted to add an Expires header:</p>
  
  <pre><code>$response = Craft::$app-&gt;getResponse();
  $response-&gt;headers-&gt;set('Expires', gmdate('D, d M Y H:i:s \G\M\T', strtotime("+1 month")));
  </code></pre>
  
  <p><a href="http://www.yiiframework.com/doc-2.0/guide-runtime-responses.html" rel="noreferrer">Yii2 Responses</a></p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-12-31T14:14:44.760Z
Answers.LastActivityDate: 2017-12-31T17:07:39.497Z
Answers.LastEditDate: 2017-12-31T17:07:39.497Z
Answers.UserDisplayName: andrew.welch
Answers.Body: <p>You can do this by assigning your endpoint(s) to a function:</p>
  
  
  
  <pre class="lang-php prettyprint-override"><code>return [
      'endpoints' =&gt; [
          'my-endpoint' =&gt; function() {
              HeaderHelper::setHeader(['Surrogate-Control: max-age=300']);
  
              return [
                  // ...
              ];
          }
      ]
  ];
  </code></pre>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Alternatively as of v1.2, you can do it from a separate plugin using the <code>onBeforeSendData</code> event:</p>
  
  <pre class="lang-php prettyprint-override"><code>public function init()
  {
      craft()-&gt;on('elementApi.onBeforeSendData', function(Event $event) {
          HeaderHelper::setHeader(['Surrogate-Control: max-age=300']);
      });
  }
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-02T01:12:14.657Z
Answers.Text: This is great! if I already have 30+ endpoints setup, is there a better way to share this across all of them? No worries if not, I can copy/paste. Just curious.
Answers.UserDisplayName: Paulo
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-02T13:54:47.280Z
Answers.Text: @Paulo Just released v1.2 with a new `onBeforeSendData` event that will give you a DRY way to do this. Updated my answer with details.
Answers.UserDisplayName: Brandon Kelly
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-02T16:44:28.863Z
Answers.Text: Yes! I'll give it a try today
Answers.UserDisplayName: Paulo
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-04-01T23:49:30.857Z
Answers.LastActivityDate: 2016-04-02T13:53:41.510Z
Answers.LastEditDate: 2016-04-02T13:53:41.510Z
Answers.UserDisplayName: Brandon Kelly
Body: <p>I need to add the a custom header to the ElementAPI endpoints I setup but I want to avoid editing the source of the plugin. What is the best way to go about this?</p>
  
  <p>The ElementAPI plugin returns some default headers by using:</p>
  
  <p><code>JsonHelper::sendJsonHeaders()</code></p>
  
  <p>To quickly achieve what I needed I added the following to the <code>ElementApiControllor.php</code>:</p>
  
  <p><code>HeaderHelper::setHeader(['Surrogate-Control: max-age=300'])</code></p>
  
  <p>This works for now but I'd love to learn how to extend existing plugins that don't have any documented hooks with my own if it is possible.</p>
  
Tags: <plugin-development><plugin-elementapi>
Title: How can I add custom headers to an ElementAPI response?
ThreadText: # How can I add custom headers to an ElementAPI response?
  
  (Asked by: username_0 on 2016-04-01)
  
  I need to add the a custom header to the ElementAPI endpoints I setup but I want to avoid editing the source of the plugin. What is the best way to go about this?
  
  The ElementAPI plugin returns some default headers by using:
  
  `JsonHelper::sendJsonHeaders()`
  
  To quickly achieve what I needed I added the following to the `ElementApiControllor.php`:
  
  `HeaderHelper::setHeader(['Surrogate-Control: max-age=300'])`
  
  This works for now but I'd love to learn how to extend existing plugins that don't have any documented hooks with my own if it is possible.
  
  **Tags:** plugin-development, plugin-elementapi
  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_2 on 2016-04-01. Score: 4 | Accepted answer
  
  You can do this by assigning your endpoint(s) to a function:
  
  ```php
  return [
      'endpoints' => [
          'my-endpoint' => function() {
              HeaderHelper::setHeader(['Surrogate-Control: max-age=300']);
  
              return [
                  // ...
              ];
          }
      ]
  ];
  
  ```
  
  **UPDATE**
  
  Alternatively as of v1.2, you can do it from a separate plugin using the `onBeforeSendData` event:
  
  ```php
  public function init()
  {
      craft()->on('elementApi.onBeforeSendData', function(Event $event) {
          HeaderHelper::setHeader(['Surrogate-Control: max-age=300']);
      });
  }
  
  ```
  
  > **Comments:**
  > **username_0**: This is great! if I already have 30+ endpoints setup, is there a better way to share this across all of them? No worries if not, I can copy/paste. Just curious.  
  > **username_2**: @username_0 Just released v1.2 with a new `onBeforeSendData` event that will give you a DRY way to do this. Updated my answer with details.  
  > **username_0**: Yes! I'll give it a try today  
  
  ---
  
  ### Answer by username_1 on 2017-12-31. Score: 5
  
  In case anyone finds this in a Google search, this is how you'd do it in Craft 3, if, say, you wanted to add an Expires header:
  
  ```
  $response = Craft::$app->getResponse();
  $response->headers->set('Expires', gmdate('D, d M Y H:i:s \G\M\T', strtotime("+1 month")));
  
  ```
  
  [Yii2 Responses](http://www.yiiframework.com/doc-2.0/guide-runtime-responses.html)
  
  
  ---
  
  