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

# Sending Surveys via Email

> Create email templates and send feedback email campaigns through the Feedback Management API

The Feedback Management API lets you collect feedback from your customers by email. You design a reusable email template, then send a campaign to a list of recipients. Each email links to one of your feedback forms, and the responses you collect feed back into Partoo's Feedback Management.

## Prerequisites

Before sending feedback emails, ensure you have:

* A valid [API key](/guides/api/resources/settings/security_and_api_key_usage) with access to Feedback Management.
* At least one **feedback form** configured for your organization. The campaign links recipients to this form.
* A **sender email** whose domain is authorized for your organization and validated for email sending. Contact your Account Manager if you are unsure whether your domain is set up.

## How sending works

A feedback email campaign ties together three things: an **email template** (how the email looks), a **feedback form** (where responses are collected), and a **recipient list** (who receives it).

```mermaid theme={null}
flowchart LR
  A[Get email template ID] --> B[Get feedback form ID]
  B --> C[Get campaign requirements]
  C --> D[Send campaign - dry run]
  D --> E[Send campaign - real]
```

Validation is **all-or-nothing**: if the sender email or any recipient fails validation, the entire campaign is rejected and **no emails are sent**. The response body details every error so you can fix the list and retry.

## Step 0 — Create an email template (optional)

<Info>
  This step is optional. Most teams design their templates visually with the
  WYSIWYG editor in the Partoo Web app. If you already have a template, skip to
  [Step 1](#step-1-get-your-email-template-id).
</Info>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST 'https://api.partoo.co/v2/feedback/email-templates' \
    -H 'x-APIKey: YOUR_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "name": "Default Template",
      "subject": "We'\''d love your feedback",
      "title": "How did we do?",
      "body": "Thank you for visiting us. Please take a moment to share your experience.",
      "cta_type": "BUTTON",
      "cta_text": "Leave a review",
      "color": "#3B82F6",
      "font_family": "Arial"
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.partoo.co/v2/feedback/email-templates",
      headers={
          "x-APIKey": "YOUR_API_KEY",
          "Content-Type": "application/json",
      },
      json={
          "name": "Default Template",
          "subject": "We'd love your feedback",
          "title": "How did we do?",
          "body": "Thank you for visiting us. Please take a moment to share your experience.",
          "cta_type": "BUTTON",
          "cta_text": "Leave a review",
          "color": "#3B82F6",
          "font_family": "Arial",
      },
  )

  template_id = response.json()["id"]
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.partoo.co/v2/feedback/email-templates",
    {
      method: "POST",
      headers: {
        "x-APIKey": "YOUR_API_KEY",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        name: "Default Template",
        subject: "We'd love your feedback",
        title: "How did we do?",
        body: "Thank you for visiting us. Please take a moment to share your experience.",
        cta_type: "BUTTON",
        cta_text: "Leave a review",
        color: "#3B82F6",
        font_family: "Arial",
      }),
    },
  );

  const {id: templateId} = await response.json();
  ```
</CodeGroup>

<Check>
  A successful response returns `201 Created` with the template's `id`. See the
  [Create an email template API
  reference](/api-reference/feedback-management/create-an-email-template) for
  the full field reference.
</Check>

## Step 1 — Get your email template ID

Templates built in the Partoo Web app are available to the API. List your organization's templates to find the `id` you want to use.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET 'https://api.partoo.co/v2/feedback/email-templates?page=1&per_page=30' \
    -H 'x-APIKey: YOUR_API_KEY'
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.partoo.co/v2/feedback/email-templates",
      headers={"x-APIKey": "YOUR_API_KEY"},
      params={"page": 1, "per_page": 30},
  )

  templates = response.json()["items"]
  template_id = templates[0]["id"]
  ```

  ```javascript Node.js theme={null}
  const params = new URLSearchParams({page: "1", per_page: "30"});

  const response = await fetch(
    `https://api.partoo.co/v2/feedback/email-templates?${params}`,
    {headers: {"x-APIKey": "YOUR_API_KEY"}},
  );

  const {items} = await response.json();
  const templateId = items[0].id;
  ```
</CodeGroup>

<Tip>
  See the [List email templates API
  reference](/api-reference/feedback-management/list-email-templates) for the
  full response schema and pagination options.
</Tip>

## Step 2 — Get your feedback form ID

Each campaign links recipients to one feedback form. Search your organization's forms to find the `feedback_form_id` you want to use.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET 'https://api.partoo.co/v2/feedback/feedback_form' \
    -H 'x-APIKey: YOUR_API_KEY'
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.partoo.co/v2/feedback/feedback_form",
      headers={"x-APIKey": "YOUR_API_KEY"},
  )

  feedback_form_id = response.json()["items"][0]["id"]
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.partoo.co/v2/feedback/feedback_form",
    {
      headers: {"x-APIKey": "YOUR_API_KEY"},
    },
  );

  const {items} = await response.json();
  const feedbackFormId = items[0].id;
  ```
</CodeGroup>

<Tip>
  See the [Search for feedback forms API
  reference](/api-reference/feedback-management/search-for-feedback-forms) for
  details.
</Tip>

## Step 3 — Get campaign requirements

Before sending, call the requirements endpoint with your `feedback_form_id` and `template_id`. It returns the exact recipient fields and template variables your payload must include, so you know which keys to provide for every recipient.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET 'https://api.partoo.co/v2/feedback/campaign/requirements?feedback_form_id=5a3f8c2e1b4d7f9a0c6e2b18&template_id=42' \
    -H 'x-APIKey: YOUR_API_KEY'
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.partoo.co/v2/feedback/campaign/requirements",
      headers={"x-APIKey": "YOUR_API_KEY"},
      params={
          "feedback_form_id": "5a3f8c2e1b4d7f9a0c6e2b18",
          "template_id": 42,
      },
  )

  requirements = response.json()
  ```

  ```javascript Node.js theme={null}
  const params = new URLSearchParams({
    feedback_form_id: "5a3f8c2e1b4d7f9a0c6e2b18",
    template_id: "42",
  });

  const response = await fetch(
    `https://api.partoo.co/v2/feedback/campaign/requirements?${params}`,
    {headers: {"x-APIKey": "YOUR_API_KEY"}},
  );

  const requirements = await response.json();
  ```
</CodeGroup>

A typical response:

```json theme={null}
{
  "feedback_form_id": "5a3f8c2e1b4d7f9a0c6e2b18",
  "template_id": 42,
  "recipient_fields": ["email_address", "unsubscribe_url"],
  "variable_fields": ["first_name", "store_code"]
}
```

* **`recipient_fields`**: Recipient-level fields supported by the send endpoint.
* **`variable_fields`**: Template variable names each recipient must provide under `variables` (sorted alphabetically). In the example above, every recipient must supply `first_name` and `store_code`.

<Tip>
  See the [Get campaign requirements API
  reference](/api-reference/feedback-management/get-campaign-requirements) for
  the full schema.
</Tip>

## Step 4 — Validate with a dry run

A dry run uses the same send endpoint (`POST /feedback/campaign/send`) with `is_dry_run: true`. It validates the sender and recipients **without sending any emails** — the safest way to confirm your list is correct before a real send.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST 'https://api.partoo.co/v2/feedback/campaign/send' \
    -H 'x-APIKey: YOUR_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{
      "feedback_form_id": "5a3f8c2e1b4d7f9a0c6e2b18",
      "feedback_email_template_id": 42,
      "sender_email": "noreply@example.com",
      "sender_name": "Acme Corp",
      "is_dry_run": true,
      "recipients": [
        {
          "email_address": "john.doe@example.com",
          "variables": { "first_name": "John", "store_code": "PAR-01" }
        }
      ]
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://api.partoo.co/v2/feedback/campaign/send",
      headers={
          "x-APIKey": "YOUR_API_KEY",
          "Content-Type": "application/json",
      },
      json={
          "feedback_form_id": "5a3f8c2e1b4d7f9a0c6e2b18",
          "feedback_email_template_id": 42,
          "sender_email": "noreply@example.com",
          "sender_name": "Acme Corp",
          "is_dry_run": True,
          "recipients": [
              {
                  "email_address": "john.doe@example.com",
                  "variables": {"first_name": "John", "store_code": "PAR-01"},
              }
          ],
      },
  )

  result = response.json()
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    "https://api.partoo.co/v2/feedback/campaign/send",
    {
      method: "POST",
      headers: {
        "x-APIKey": "YOUR_API_KEY",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        feedback_form_id: "5a3f8c2e1b4d7f9a0c6e2b18",
        feedback_email_template_id: 42,
        sender_email: "noreply@example.com",
        sender_name: "Acme Corp",
        is_dry_run: true,
        recipients: [
          {
            email_address: "john.doe@example.com",
            variables: {first_name: "John", store_code: "PAR-01"},
          },
        ],
      }),
    },
  );

  const result = await response.json();
  ```
</CodeGroup>

<Warning>
  The send endpoint returns `200 OK` for **both** accepted and rejected campaigns. Always inspect the `status` field rather than relying on the HTTP status code.

  * `status: "accepted"` — validation passed (emails enqueued, or skipped because `is_dry_run` was `true`).
  * `status: "failed"` — sender or recipient validation failed; no emails were sent. The error fields describe what to fix.
</Warning>

<Tip>
  See the [Send a feedback email campaign API
  reference](/api-reference/feedback-management/send-a-feedback-email-campaign)
  for the complete request and response schema.
</Tip>

## Step 5 — Send the campaign

Once the dry run returns `status: "accepted"`, send for real by setting `is_dry_run: false` (or omitting it — it defaults to `false`).

A successful response:

```json theme={null}
{
  "status": "accepted",
  "feedback_email_campaign_id": 101,
  "feedback_form_id": "5a3f8c2e1b4d7f9a0c6e2b18",
  "feedback_template_id": 42,
  "recipient_count": 150
}
```

<Info>
  **Batch limit**: a single call accepts at most **1000 recipients**. For larger
  lists, split them into batches and call the endpoint multiple times.
</Info>

<Tip>
  See the [Send a feedback email campaign API
  reference](/api-reference/feedback-management/send-a-feedback-email-campaign)
  for the complete request and response schema.
</Tip>
