> ## Documentation Index
> Fetch the complete documentation index at: https://docs.repdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Activity Integration

> Call the Research Defender Activity API with a POST request, authorized with your key in the x-api-key header.

## Overview

The Activity API is called with identifiers for a respondent and a time range in hours. This guide shows how to send the request with `POST`, passing the parameters as a JSON body. All parameters are optional.

Unlike the search and review APIs, the Activity API runs on `resdefio.com` and is authorized with an **authorization key** that you send in the `x-api-key` header.

## Authentication

Send your authorization key in the `x-api-key` header of every request.

<ParamField header="x-api-key" type="string" required>
  Your Research Defender authorization key.
</ParamField>

<Warning>
  Your authorization key is a secret. The sample on this page calls the API from the browser for demonstration, but anything in client-side code can be read. If you can, call the Activity API from your server and keep the key there.
</Warning>

## Endpoint

<ParamField path="Endpoint" type="string">
  `POST https://{environment}.resdefio.com/activity`
</ParamField>

| Environment | Endpoint |
| - | - |
| `prod` | `https://prod.resdefio.com/activity` |
| `stage` | `https://stage.resdefio.com/activity` |

In the sample, set `ENVIRONMENT` to `"prod"` or `"stage"`.

## Request body

Send the parameters as a JSON object. All parameters are optional.

<ParamField body="Survey_Number" type="string">
  The survey number. Optional.
</ParamField>

<ParamField body="Session_Id" type="string">
  The respondent's session ID. Optional.
</ParamField>

<ParamField body="Panel_Id" type="string">
  The panel ID. Optional.
</ParamField>

<ParamField body="Hashed_Email" type="string">
  The respondent's hashed email address. Optional.
</ParamField>

<ParamField body="Range" type="number" default="24">
  The time range in hours. Optional. If you leave it out, `24` is used.
</ParamField>

### Range values

`Range` accepts one of these values, in hours.

| Value | Time range |
| - | - |
| `1` | 1 hour |
| `3` | 3 hours |
| `8` | 8 hours |
| `12` | 12 hours |
| `24` | 24 hours (default) |
| `168` | 168 hours (7 days) |
| `730` | 730 hours (about 30 days) |

### Sending more parameters

The sample sends `Survey_Number` and `Session_Id`. To send `Panel_Id`, `Hashed_Email`, or `Range`, add them to the object in `buildPayload()`. A request body with every parameter looks like this:

```json theme={null}
{
  "Survey_Number": "YOUR_SURVEY_NUMBER",
  "Session_Id": "YOUR_SESSION_ID",
  "Panel_Id": "YOUR_PANEL_ID",
  "Hashed_Email": "YOUR_HASHED_EMAIL",
  "Range": 24
}
```

## Example

<Tabs>
  <Tab title="JavaScript">
    ```javascript activity-post.js theme={null}
    // ---------------------------------------------------------------
    // Configuration
    // ---------------------------------------------------------------
    const ENVIRONMENT = "prod"; // "stage" or "prod"

    // Your authorization key, sent in the x-api-key header. Keep it secret.
    // This sample calls the API from the browser for demonstration only. Anything
    // in client-side code can be read, so call the API from your server if you can.
    const API_KEY = "YOUR_API_KEY";

    // Optional parameters. Set a value to "" to leave it out of the request.
    // Other optional parameters are described in the documentation.
    const SURVEY_NUMBER = "YOUR_SURVEY_NUMBER"; // Survey_Number (optional)
    const SESSION_ID = "YOUR_SESSION_ID";       // Session_Id (optional)

    const ACTIVITY_ENDPOINT = `https://${ENVIRONMENT}.resdefio.com/activity`;

    // ---------------------------------------------------------------
    // Helpers
    // ---------------------------------------------------------------

    /** Builds the request body. Empty values are left out. */
    function buildPayload() {
      const payload = {
        Survey_Number: SURVEY_NUMBER,
        Session_Id: SESSION_ID,
      };

      return Object.fromEntries(
        Object.entries(payload).filter(([, value]) => value !== "" && value != null)
      );
    }

    /** Parses a response body as JSON, or returns the raw text if it is not JSON. */
    function parseResponse(text) {
      try {
        return JSON.parse(text);
      } catch {
        return text;
      }
    }

    /** Sends the POST request and returns the parsed result. */
    async function getActivity(payload) {
      const response = await fetch(ACTIVITY_ENDPOINT, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "x-api-key": API_KEY, // authorization key
        },
        body: JSON.stringify(payload),
      });

      const text = await response.text();

      if (!response.ok) {
        throw new Error(`Activity request failed with status ${response.status}: ${text.slice(0, 300)}`);
      }

      return parseResponse(text);
    }

    // ---------------------------------------------------------------
    // Usage
    // ---------------------------------------------------------------
    const result = await getActivity(buildPayload());
    console.log("Activity result:", result);
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={null}
    curl -X POST "https://prod.resdefio.com/activity" \
      -H "Content-Type: application/json" \
      -H "x-api-key: YOUR_API_KEY" \
      -d '{
        "Survey_Number": "YOUR_SURVEY_NUMBER",
        "Session_Id": "YOUR_SESSION_ID"
      }'
    ```
  </Tab>
</Tabs>

The JavaScript example builds the body with `buildPayload()`, which leaves out empty values. `getActivity()` sends the request with the `Content-Type` and `x-api-key` headers and shows the API's message if the request fails.

## Full HTML page

If you want a complete page you can open in a browser, use the sample below. Replace the placeholder values at the top of the script.

<Accordion title="Activity integration with POST (HTML)">
  ```html activity-post-integration.html theme={null}
  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Research Defender – Activity Integration (POST)</title>
  </head>
  <body>
    <h1>Research Defender – Activity Integration (POST)</h1>
    <pre id="output">Loading…</pre>

    <script>
      // ---------------------------------------------------------------
      // Configuration
      // ---------------------------------------------------------------
      const ENVIRONMENT = "prod"; // "stage" or "prod"

      // Your authorization key, sent in the x-api-key header. Keep it secret.
      // This sample calls the API from the browser for demonstration only. Anything
      // in client-side code can be read, so call the API from your server if you can.
      const API_KEY = "YOUR_API_KEY";

      // Optional parameters. Set a value to "" to leave it out of the request.
      // Other optional parameters are described in the documentation.
      const SURVEY_NUMBER = "YOUR_SURVEY_NUMBER"; // Survey_Number (optional)
      const SESSION_ID = "YOUR_SESSION_ID";       // Session_Id (optional)

      const ACTIVITY_ENDPOINT = `https://${ENVIRONMENT}.resdefio.com/activity`;

      // ---------------------------------------------------------------
      // Helpers
      // ---------------------------------------------------------------

      /** Builds the request body. Empty values are left out. */
      function buildPayload() {
        const payload = {
          Survey_Number: SURVEY_NUMBER,
          Session_Id: SESSION_ID,
        };

        return Object.fromEntries(
          Object.entries(payload).filter(([, value]) => value !== "" && value != null)
        );
      }

      /** Parses a response body as JSON, or returns the raw text if it is not JSON. */
      function parseResponse(text) {
        try {
          return JSON.parse(text);
        } catch {
          return text;
        }
      }

      /** Sends the POST request and returns the parsed result. */
      async function getActivity(payload) {
        const response = await fetch(ACTIVITY_ENDPOINT, {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
            "x-api-key": API_KEY, // authorization key
          },
          body: JSON.stringify(payload),
        });

        const text = await response.text();

        if (!response.ok) {
          throw new Error(`Activity request failed with status ${response.status}: ${text.slice(0, 300)}`);
        }

        return parseResponse(text);
      }

      // ---------------------------------------------------------------
      // Run
      // ---------------------------------------------------------------
      window.addEventListener("load", async () => {
        const output = document.getElementById("output");

        try {
          const result = await getActivity(buildPayload());

          console.log("Activity result:", result);
          output.textContent =
            typeof result === "string" ? result : JSON.stringify(result, null, 2);
        } catch (error) {
          console.error(error);
          output.textContent = `Error: ${error.message}`;
        }
      });
    </script>
  </body>
  </html>
  ```
</Accordion>

## Troubleshooting

| Symptom | Likely cause |
| - | - |
| The request is rejected with an authorization error | The `x-api-key` header is missing or the key is wrong. |
| The request is rejected after you add `Range` | Use one of the listed Range values: 1, 3, 8, 12, 24, 168, or 730. |
| The request is blocked in the browser | The browser could not complete the request to `resdefio.com`. Check the browser console, and consider calling the API from your server. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.