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

# ETL: Trustpilot Destination

> Send one service-review email invitation per input record through Trustpilot's Invitations API from an Integrate.io ETL pipeline.

Use the Trustpilot destination to send service-review email invitations from your ETL pipeline. The component posts one invitation to Trustpilot's Invitations API for every input record, using an invitation template you have already defined in the Trustpilot Business portal.

<Warning>
  Every record that succeeds puts an email in a real consumer's inbox. There is no dry run and no undo. Tasks are not retried on failure, because a retried attempt would re-send every invitation the failed attempt already delivered. Test on a small sample before running against a full dataset.
</Warning>

## When to use it

Use this destination to trigger post-purchase or post-interaction review invitations from data already in your pipeline. Typical inputs are order or ticket records with a customer email address and your internal reference number for the transaction.

For reading service reviews and business categories back out of Trustpilot, use the [Trustpilot source](/docs/etl/using-components-trustpilot-source) instead.

## Connection

Select an existing Trustpilot connection or create a new one. The destination has two requirements the source does not:

* **API Secret** must be set on the connection. The invitations endpoint accepts only OAuth bearer tokens, and Trustpilot mints those through the `client_credentials` flow, which needs both the API Key and the API Secret.
* **Business User ID** must be set on the connection. Trustpilot requires it on every invitation request as the `x-business-user-id` header.

If either field is missing, the component reports a validation error naming the missing field. Edit the connection, add the value, and re-test the connection.

See [Connecting to Trustpilot](/docs/etl/using-components-trustpilot-source#connection-setup) for how to create the connection.

## Destination properties

* **Invitation template** - the Trustpilot template that will be sent. The dropdown is populated from Trustpilot's `GET /v1/private/business-units/{businessUnitId}/templates` endpoint, cached for one hour. Use the refresh control next to the dropdown to bypass the cache after you add or rename a template in Trustpilot.
* **Sender name** - default sender display name on the invitation. Overridden per row when a `senderName` field is mapped.
* **Sender email** - default sender address. Overridden per row when a `senderEmail` field is mapped. Must be a valid email address.
* **Reply-to** - default reply-to address. Overridden per row when a `replyTo` field is mapped. Must be a valid email address.
* **Locale** - default locale (for example `en-US`, `de-DE`). Overridden per row when a `locale` field is mapped.

### Advanced options

* **Requests per second** - throttle applied to the invitations API. Default is `5`, matching Trustpilot's documented application rate limit. Maximum is `100`. The component uses a single reducer, so this value is the real request rate against Trustpilot.
* **Maximum failed records** - the job fails once cumulative failed invitations exceed this value. Default is `0` (fail on the first failure). Set to `-1` for unlimited failures.

## Field mapping

The invitation payload is a fixed schema. Map input fields to Trustpilot invitation fields by exact name.

**Required fields** (every invitation needs these):

| Field             | Description                                                                                                        |
| :---------------- | :----------------------------------------------------------------------------------------------------------------- |
| `consumerEmail`   | Recipient address. The invitation is sent here.                                                                    |
| `consumerName`    | Recipient display name shown in the email.                                                                         |
| `referenceNumber` | Your own reference for the order or interaction being reviewed. Trustpilot stores it against the resulting review. |

**Optional fields** (overrides per row):

| Field               | Description                                                            |
| :------------------ | :--------------------------------------------------------------------- |
| `senderName`        | Overrides the component-level sender name for this row.                |
| `senderEmail`       | Overrides the component-level sender email for this row.               |
| `replyTo`           | Overrides the component-level reply-to address for this row.           |
| `locale`            | Overrides the component-level locale for this row.                     |
| `templateId`        | Overrides the component-level template for this row.                   |
| `redirectUri`       | URL Trustpilot redirects the consumer to after they submit the review. |
| `preferredSendTime` | ISO 8601 timestamp for when Trustpilot should send the invitation.     |
| `tags`              | Tags attached to the resulting review invitation.                      |

The component raises a build-time error if any required field is missing from the mapping, or if a mapped field is not one of the fields listed above. Catching this up front avoids a run where a missing field fails every record.

## Success and error tracking

The destination can write two CSVs to a cloud storage connection for reconciliation. Both are optional and configured independently.

* **Track successful records** - writes a CSV of records that were accepted by Trustpilot, one row per invitation sent.
* **Track failed records** - writes a CSV of records that were rejected, one row per failure, with the Trustpilot error message for each.

Supported storage connections for either output: Amazon S3, Google Cloud Storage, Azure Blob Storage, SFTP, and FTPS.

If an invitation batch produces no rows for a given CSV (for example, a successful run with zero failures), the file is not written, so an empty invocation does not leave header-only files in your bucket.

## Example: post-purchase invitations from a Snowflake query

A pipeline that reads yesterday's completed orders from Snowflake and sends one Trustpilot invitation per order:

```sql theme={null}
-- Snowflake source query
SELECT
  customer_email   AS "consumerEmail",
  customer_name    AS "consumerName",
  order_id         AS "referenceNumber",
  order_locale     AS "locale"
FROM orders
WHERE status = 'completed'
  AND completed_at >= DATEADD(day, -1, CURRENT_TIMESTAMP())
```

Map each aliased column to the Trustpilot field of the same name. Set **Sender name**, **Sender email**, **Reply-to**, and **Invitation template** on the component so every row inherits them. Leave `senderName`, `senderEmail`, `replyTo`, and `templateId` unmapped. Enable **Track failed records** to an S3 bucket so you can review rejected addresses after the run.

## Related

<CardGroup cols={2}>
  <Card title="Trustpilot Source" icon="arrow-right" href="/docs/etl/using-components-trustpilot-source" horizontal />

  <Card title="Salesforce REST API Destination" icon="arrow-right" href="/docs/etl/using-components-salesforce-rest-destination" horizontal />

  <Card title="HubSpot Destination" icon="arrow-right" href="/docs/etl/using-components-hubspot-destination" horizontal />

  <Card title="Destinations Overview" icon="arrow-right" href="/docs/etl/category/destinations" horizontal />
</CardGroup>
