# API Tokens Source: https://help.privy.com/docs/api-reference/api-tokens Create API tokens for a simpler way to authenticate with the Privy API. API tokens are a lightweight alternative to [OAuth applications](/docs/api-reference/authentication) for authenticating with the Privy API. Instead of exchanging client credentials for a short-lived OAuth access token, you generate a longer-lived token directly from the dashboard and use it immediately. | | API Tokens | OAuth Applications | | ------------------ | ------------------------------------------- | ---------------------------------------------------- | | **Setup** | Generate a token in the dashboard | Create an app, then exchange credentials for a token | | **Token lifetime** | 30 days to 1 year (or no expiry) | 2 hours | | **Best for** | Scripts, internal tools, quick integrations | Third-party integrations, automated token rotation | ## Creating a token Navigate to **Settings > API Tokens** in your [Privy dashboard](https://dashboard.privy.com). Click **Create Token**. Choose a descriptive name, select the scopes you need, and pick an expiration period. The token is displayed **once** after creation. Copy it immediately and store it securely — you won't be able to view it again. Treat API tokens like passwords. Never share them in client-side code, public repositories, or URLs. If a token is compromised, revoke it immediately from the dashboard. ## Token format API tokens use the prefix `privy_` followed by a 40-character hex string: ``` privy_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 ``` ## Scopes Scopes control what your token can access. You select scopes when creating the token. | Scope | Description | | ---------------- | ------------------------------------------------ | | `contacts_read` | List and filter contacts | | `contacts_write` | Create, update, unsubscribe, and delete contacts | | `events_write` | Ingest custom events | | `orders_write` | Create and update orders | ## Using a token Include the token in the `Authorization` header as a bearer token — exactly the same as an OAuth access token: ```bash theme={null} curl -X GET "https://api.privy.com/v1/contacts" \ -H "Authorization: Bearer privy_YOUR_TOKEN" ``` All API endpoints accept API tokens and OAuth access tokens in the same `Authorization` header format. ## Expiration When creating a token, choose from the following lifetimes: | Option | Duration | | ------------- | -------------------------------------- | | 30 days | Token expires 30 days after creation | | 60 days | Token expires 60 days after creation | | 90 days | Token expires 90 days after creation | | 1 year | Token expires 1 year after creation | | No expiration | Token never expires (use with caution) | Tokens that were created with an expiration can be **renewed** from the dashboard to extend them by their original duration. ## Revoking a token You can revoke a token at any time from **Settings > API Tokens** in the dashboard. Revoked tokens are rejected immediately — any request using a revoked token receives a `401` error. ## Limits Each Privy account can have up to **25 active API tokens** at a time. Revoked and expired tokens do not count toward this limit. [Rate limits](/docs/api-reference/rate-limits) apply to API tokens the same way they apply to OAuth access tokens — all requests under the same account share the same rate limit budget. ## Error responses | Status | Code | Cause | | ------ | -------------------- | -------------------------------------------------------- | | `401` | `unauthorized` | Token is missing, invalid, expired, or revoked | | `403` | `insufficient_scope` | Token does not have the required scope for this endpoint | See the [Errors](/docs/api-reference/errors) page for all error codes. # Authentication Source: https://help.privy.com/docs/api-reference/authentication How to authenticate with the Privy API using OAuth 2.0 bearer tokens or API tokens. The Privy API supports two authentication methods. Both methods produce a bearer token that you send in the `Authorization` header: * **[API tokens](/docs/api-reference/api-tokens)** — Generate a long-lived token from the dashboard and use it directly. Best for scripts and quick integrations. * **OAuth applications** — Exchange client credentials for a short-lived access token. Best for third-party integrations with automated rotation. ## OAuth: How it works 1. Create an OAuth application in your Privy dashboard to get a **client ID** and **client secret**. 2. Exchange those credentials for an access token using the OAuth 2.0 client credentials flow. 3. Include the access token in the `Authorization` header of every request. ```bash theme={null} curl -X GET "https://api.privy.com/v1/contacts" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` ## Creating an OAuth application Navigate to **Settings > API > API Tokens** in your [Privy dashboard](https://dashboard.privy.com) and create a new application. You'll choose a name and select which scopes the application should have access to. By default, no scopes are assigned. When the application is created, the dashboard displays the **client secret once**. Copy it immediately — you won't be able to view it again. If you lose it, you can regenerate a new secret from the application's settings. ## Scopes Scopes control what your token can access. Your OAuth application must have a scope enabled before you can request it — configure scopes in **Settings > API > API Tokens** in your dashboard. | Scope | Description | Default | | ---------------- | ------------------------------------------------ | ------- | | `contacts_read` | List and filter contacts | Yes | | `contacts_write` | Create, update, unsubscribe, and delete contacts | No | | `events_write` | Ingest custom events | No | | `orders_write` | Create and update orders | No | ## Getting an access token Exchange your client ID and client secret for an access token by making a `POST` request to the token endpoint. ### Read-only access To read contacts, request the `contacts_read` scope explicitly: ```bash theme={null} curl -X POST "https://api.privy.com/oauth/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials" \ -d "client_id=YOUR_CLIENT_ID" \ -d "client_secret=YOUR_CLIENT_SECRET" \ -d "scopes=contacts_read" ``` ```json theme={null} { "access_token": "eyJhbGciOi...", "token_type": "Bearer", "expires_in": 7200, "scope": "contacts_read", "created_at": 1712150400 } ``` ### Read and write access To create, update, or delete contacts, request the `contacts_write` scope explicitly: ```bash theme={null} curl -X POST "https://api.privy.com/oauth/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials" \ -d "client_id=YOUR_CLIENT_ID" \ -d "client_secret=YOUR_CLIENT_SECRET" \ -d "scope=contacts_read contacts_write" ``` ```json theme={null} { "access_token": "eyJhbGciOi...", "token_type": "Bearer", "expires_in": 7200, "scope": "contacts_read contacts_write", "created_at": 1712150400 } ``` The `scope` response field confirms which scopes were actually granted. Always check this to verify your token has the access you need. | Field | Description | | -------------- | --------------------------------------------------------------------------------- | | `access_token` | The bearer token to include in API requests. | | `token_type` | Always `Bearer`. | | `expires_in` | Token lifetime in seconds. Access tokens expire after **2 hours** (7200 seconds). | | `scope` | The scopes granted to this token. | If your client ID or secret is wrong, the token endpoint returns a `401` error with `invalid_client`. If you request a scope that isn't enabled on your application, it returns `invalid_scope`. ### Refreshing tokens When your access token expires, request a new one by repeating the client credentials exchange above. There is no refresh token in the client credentials flow — simply request a new access token. ## Security tips * **Keep credentials secret.** Never share your client secret or access tokens in client-side code, public repositories, or URLs. * **Rotate secrets regularly.** Regenerate your client secret periodically from the dashboard, especially if a team member leaves. * **Use one application per integration.** This makes it easy to revoke access for a single integration without affecting others. ## Invalid tokens If your bearer token is missing, expired, revoked, or malformed, API endpoints return a `401 unauthorized` error: ```json theme={null} { "error": { "code": "unauthorized", "message": "Bearer token is missing or invalid" } } ``` See the [Errors](/docs/api-reference/errors) page for all error codes. # API Changelog Source: https://help.privy.com/docs/api-reference/changelog Updates, additions, and breaking changes to the Privy API. This page tracks user-facing changes to the Privy API. Dates reflect the day a change went live in production. For migration help, email [support@privy.com](mailto:support@privy.com). ## 2026-07-03 ### Added `POST /v1/events` endpoint You can send custom events to Privy through the API with the `POST /v1/events` endpoint. Accepted events can trigger **Flows** and other automations, keyed on the `event_type` you send. A successful `200` response means the event was accepted for processing — it does not guarantee a specific automation ran. *** ## 2026-06-22 ### Added `POST /v1/orders/placed` endpoint You can create and update orders through the API with the `POST /v1/orders/placed` endpoint, available under the `orders_write` OAuth scope. The endpoint is an **idempotent upsert** keyed on `order_id`: the first call for a given `order_id` creates the order and returns `201 Created`, while subsequent calls with the same `order_id` update the existing order and return `200 OK`. Send the full current state of the order on every call — omitted optional fields keep their previously stored values. * **Required fields:** `order_id`, `total`, `currency`, `order_date`, plus at least one of `email` or `phone`. * **Customer linkage.** When an `email` or `phone` is provided, Privy finds or creates the matching contact. `accepts_email_marketing` drives email subscribe-on-create semantics, and `accepts_sms_marketing` records an SMS opt-in on newly created contacts (requires `phone`). * **Historical imports.** Pass `initial_sync: true` to load past orders without triggering real-time side effects such as flows, automations, and campaign-revenue attribution. Customer order stats are still updated so segmentation and winback stay accurate. ### Tie orders to a Custom Integration with `X-Privy-Integration-Token` `POST /v1/orders/placed` accepts an optional `X-Privy-Integration-Token` header that attributes the order to a specific Custom Integration. Generate the token when you create a Custom Integration in **Settings → Integrations Hub**, and retrieve it later with the **Reveal** action. * When the header is present, it must match an active Custom Integration for your business. * When the header is omitted and exactly one Custom Integration exists, the order is automatically tied to it. * Otherwise, the order is created with no integration attribution. The header is sent **in addition to** your standard `Authorization: Bearer` OAuth token, which still authenticates the request. *** ## 2026-05-22 ### Welcome SMS for API-created SMS subscribers When you set `sms_consent` to `subscribed` via `POST /v1/contacts` or `PATCH /v1/contacts/{id}`, Privy now automatically sends a TCPA-required welcome SMS to the contact. This only fires when the contact actually transitions to a confirmed opt-in state — contacts that are already subscribed are not messaged again. To suppress the welcome SMS (for example, when you already collected consent outside of Privy), pass `send_welcome_sms: false` in the request body. The parameter defaults to `true`. *** ## 2026-05-14 ### Contact creation conflict responses now include `id` `POST /v1/contacts` now returns the `id` of the existing contact in `409 Conflict` responses, nested inside the `error` object (`error.id`). This lets API consumers identify and update the existing contact without a separate lookup. *** ## 2026-05-12 ### Consent vocabulary and PATCH-based consent management **Breaking changes:** * **Response field renames.** Contact responses now return `email_consent` and `sms_consent` instead of `email_permission` and `phone_permission`. * **Filter parameter renames.** The `GET /v1/contacts` query parameters `email_permission` and `phone_permission` have been renamed to `email_consent` and `sms_consent`. * **New consent values.** The old `non_subscribed` value has been replaced by `never_subscribed`. New values have been added — see below. **New features:** * **Consent management via PATCH.** `PATCH /v1/contacts/{id}` now accepts `email_consent` and `sms_consent` fields. You can combine consent changes with other field updates in a single request. * **Consent on create.** `POST /v1/contacts` now accepts the full set of writable consent values for `email_consent` and `sms_consent`. * **Expanded email consent values:** * `subscribed` — contact opted into email. * `unsubscribed` — contact opted out of email. * `never_subscribed` — no opt-in, no opt-out (replaces `non_subscribed`). * `suppressed` — merchant-suppressed (writable). Writing any consent value to a merchant-suppressed contact unsuppresses it first. * `compliance_suppressed` — system-suppressed (read-only, filterable). Any write to a compliance-suppressed contact returns `422`. * **Expanded SMS consent values:** * `subscribed` — contact has confirmed SMS opt-in. * `unsubscribed` — contact opted out of SMS. * `never_subscribed` — no opt-in, no opt-out (replaces `non_subscribed`). * `single_opt_in` — merchant collected a single opt-in (not yet confirmed). Writable; requires a phone number. * `pending` — awaiting confirmation reply (read-only, filterable). **Deprecations:** * **`POST /v1/contacts/{id}/unsubscribe` is deprecated.** Use `PATCH /v1/contacts/{id}` with `email_consent: "unsubscribed"` instead. The endpoint continues to work but now returns `Deprecation: true` and `Link` headers. # Create a contact Source: https://help.privy.com/docs/api-reference/create-contact openapi/privy-api.yaml POST /contacts Create a new contact. At least one of `email` or `phone_number` is required. If a contact with the same email or phone number already exists, a `409 Conflict` error is returned with the `id` of the existing contact in `error.id`. Use the **Update a contact** endpoint to modify existing contacts. If a previously deleted contact matches the provided email or phone number, the contact is restored with the new data. When `sms_consent` is `subscribed`, Privy automatically sends a TCPA-required welcome SMS to the contact. Pass `send_welcome_sms: false` to suppress this message if you have already collected consent outside of Privy. **Required scope:** `contacts_write` # Delete a contact Source: https://help.privy.com/docs/api-reference/delete-contact openapi/privy-api.yaml DELETE /contacts/{id} Soft-delete a contact identified by its unique `id`. Deleted contacts can be restored if a new contact is created with the same email or phone number via the **Create a contact** endpoint. **Required scope:** `contacts_write` # Errors Source: https://help.privy.com/docs/api-reference/errors Error response format and common error codes. When an API endpoint request fails, the API returns a JSON error response with a consistent structure. ## Error format API endpoint errors follow this envelope: ```json theme={null} { "error": { "code": "validation_failed", "message": "One or more fields are invalid", "details": [ { "field": "email", "message": "is required" } ] } } ``` | Field | Description | | --------- | ------------------------------------------------------------------------ | | `code` | A machine-readable error code (see table below) | | `message` | A human-readable description of what went wrong | | `details` | An optional array of field-level errors (present on validation failures) | ## Error codes This table also includes OAuth token endpoint errors. Those happen before you have a bearer token and are returned by `/oauth/token`. | Code | HTTP Status | Description | | -------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `invalid_client` | 401 | Client ID or client secret is incorrect. Returned by the `/oauth/token` endpoint. | | `invalid_scope` | 401 | The requested OAuth scope is not enabled on the application. Returned by the `/oauth/token` endpoint. | | `unauthorized` | 401 | Bearer token is missing, expired, revoked, or invalid. OAuth access tokens expire after 2 hours. API token lifetimes depend on the expiration chosen when the token was created. | | `insufficient_scope` | 403 | Token does not have the required scope for this endpoint. See [Scopes](/docs/api-reference/authentication#scopes). | | `not_found` | 404 | The contact could not be found | | `conflict` | 409 | A contact with this email or phone number already exists | | `validation_failed` | 422 | One or more fields failed validation | | `payload_too_large` | 413 | The request body exceeds the endpoint's size limit (256 KB for [Ingest an event](/docs/api-reference/ingest-event)) | | `rate_limited` | 429 | Rate limit exceeded — see [Rate Limits](/docs/api-reference/rate-limits) | ## Validation errors A `422 validation_failed` response includes a `details` array with specific field errors. For example, creating a contact without an email or phone number returns: ```json theme={null} { "error": { "code": "validation_failed", "message": "One or more fields are invalid", "details": [ { "field": "base", "message": "email or phone_number is required" } ] } } ``` Common validation messages: | Field | Message | | ------------------------ | --------------------------------------------------------------------------- | | `email` / `phone_number` | `email or phone_number is required` | | `phone_number` | `must be a valid phone number in E.164 format` | | `email_consent` | `must be one of: subscribed, unsubscribed, never_subscribed, suppressed` | | `sms_consent` | `must be one of: subscribed, unsubscribed, never_subscribed, single_opt_in` | | `sms_consent` | `requires a phone number from a supported country` | | `custom_fields` | `must be a flat key-value object (no nested values)` | ## Conflict errors A `409 conflict` is returned when you try to create a contact with an email or phone number that already belongs to an existing contact. The response includes the `id` of the existing contact, nested inside the `error` object, so you can update it directly. ```json theme={null} { "error": { "code": "conflict", "message": "A contact with this email already exists", "id": "cus_x9y8z7w6v5u4t3s2" } } ``` To update the existing contact, use the [Update a contact](/docs/api-reference/update-contact) endpoint with the returned `error.id`. ## Event ingest errors The [Ingest an event](/docs/api-reference/ingest-event) endpoint is an exception: a payload that fails validation returns `400` with a **top-level `errors` array** rather than the standard `error` envelope, and a `status` of `rejected`. ```json theme={null} { "event_id": "507f1f77bcf86cd799439012", "status": "rejected", "errors": [ { "field": "identifier", "message": "email, phone, or privy_id is required" }, { "field": "event_type", "message": "is required" } ] } ``` Auth, scope, size, and rate-limit failures on that endpoint (`401`, `403`, `413`, `429`) still use the standard `error` envelope above. ## Handling errors 1. **Check the HTTP status code first.** The status code tells you the category of error. 2. **Parse the error body.** Use the `code` field for programmatic handling and the `message` for logging. 3. **Only retry on `429`.** Rate limit errors are temporary — wait for `Retry-After` seconds, then retry. Other errors require fixing the request. # Get a contact Source: https://help.privy.com/docs/api-reference/get-contact openapi/privy-api.yaml GET /contacts/{id} Retrieve a single contact by its unique `id`. **Required scope:** `contacts_read` # Ingest an event Source: https://help.privy.com/docs/api-reference/ingest-event openapi/privy-api.yaml POST /events Send a custom event to Privy. Use events to trigger **Flows** and other automations from activity in your own systems (a completed purchase, a finished quiz, a loyalty milestone, etc.). Identify the contact with **exactly one** of `email`, `phone`, or `privy_id`. If the contact doesn't exist yet, Privy creates one (by email or phone); `privy_id` must reference an existing contact. ## Response status Unlike most endpoints, a successful ingest returns **`200 OK`** with a `status` field rather than `201`. A payload that fails validation returns **`400 Bad Request`** with a top-level `errors` array — a different shape from the standard `error` envelope used for auth and rate-limit errors. ## Idempotency Set the `Idempotency-Key` header (or an `idempotency_key` body field; the header wins if both are present) to safely retry. The first request ingests the event; a retry with the same key returns the original response with `idempotent_replay: true` instead of ingesting a duplicate. Only accepted events are replayed — a rejected payload re-validates on retry. ## Limits The request body must not exceed **256 KB**; larger bodies return `413`. **Required scope:** `events_write` Accepted events can trigger **Flows** and other automations, keyed on the `event_type` you send. A successful `200` response means the event was accepted for processing — it does not guarantee a specific automation ran. # List contacts Source: https://help.privy.com/docs/api-reference/list-contacts openapi/privy-api.yaml GET /contacts Retrieve a paginated list of contacts, most recently created first. Optionally filter by email, phone number, or consent status. Unfiltered, the list covers every contact in the account whatever their consent state, so `pagination.total_count` is the size of your contact list — not the size of your mailable or textable audience. Filter on `email_consent=subscribed` or `sms_consent=subscribed` for those. Contacts you have deleted are excluded — but deletion is soft: creating a contact with the same email or phone number restores the existing record rather than creating a new one, so a previously deleted contact can reappear here later with its original id and history. **Required scope:** `contacts_read` # Order placed Source: https://help.privy.com/docs/api-reference/order-placed openapi/privy-api.yaml POST /orders/placed Report an order placed in your store. This is an **idempotent upsert** keyed on `order_id`: the first call for an `order_id` creates the order and returns `201 Created`; subsequent calls with the same `order_id` update it and return `200 OK`. The order carries the full current state each time — omitted optional fields keep their previously stored value. The order is associated to a contact by `email` (or, when no email is sent, by `phone`), creating the contact if needed. `accepts_email_marketing` and `accepts_sms_marketing` drive the contact's marketing consent — see the field descriptions for the exact semantics. Optionally send the `X-Privy-Integration-Token` header to tie the order to a specific Custom Integration (see the header parameter below). **Required scope:** `orders_write` To trigger Privy **Flows** (such as Order Placed and Order Received) from orders sent to this endpoint, you must first connect a [Custom Integration](/docs/learn/integrations/custom-integration) for your store. See [Flows currently available](/docs/learn/integrations/custom-integration#flows-currently-available) for the supported triggers and conditions. # API Overview Source: https://help.privy.com/docs/api-reference/overview Use Privy's API to connect your own tools, scripts, or agents to your Privy account. Please note API access is only available to paid accounts. If requests fail despite valid credentials, confirm with [Support](mailto:support@privy.com) that API access is available for your account. Use Privy's API to connect your own tools, scripts, or agents to your Privy account. With the API, you can: * [Create contacts](/docs/api-reference/create-contact) * [Update contact or consent properties](https://help.privy.com/docs/api-reference/update-contact) * **[Send order events](/docs/api-reference/order-placed)** to trigger Flows and populate order data in your Privy account * [Send custom events](/docs/api-reference/ingest-event) to trigger Flows from activity in your own systems ## Base URL All API requests use the following base URL: ```text theme={null} https://api.privy.com/v1 ``` ## Quick start The fastest way to get started is to create an **API token** from **Settings > API Tokens** in your [Privy dashboard](https://dashboard.privy.com). See [API Tokens](/docs/api-reference/api-tokens) for details. Alternatively, create an OAuth application under **Settings > API > API Tokens** to use the [OAuth client credentials flow](/docs/api-reference/authentication). Use your bearer token to list your contacts: ```bash theme={null} curl -X GET "https://api.privy.com/v1/contacts" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" ``` You'll receive a JSON response with your contact data and pagination info: ```json theme={null} { "data": [ { "id": "cus_a1b2c3d4e5f6g7h8", "first_name": "Jane", "last_name": "Doe", "email": "jane@example.com", "email_consent": "subscribed", "phone_number": "+15551234567", "sms_consent": "subscribed", "tags": ["vip"], "custom_fields": { "loyalty_tier": "gold" }, "created_at": "2025-01-15T10:30:00Z", "updated_at": "2025-03-20T14:22:00Z" } ], "pagination": { "page": 1, "per_page": 25, "total_count": 142, "total_pages": 6 } } ``` ## Next steps Generate a token and start making requests in minutes. Set up OAuth credentials and learn about scopes. Understand request limits and how to handle them. Learn about error codes and response format. # Rate Limits Source: https://help.privy.com/docs/api-reference/rate-limits Understand rate limits and how to handle them gracefully. The Privy API enforces rate limits to ensure fair usage and reliable performance for all accounts. ## Default limits | Window | Limit | | ---------- | --------------- | | Per minute | 60 requests | | Per day | 10,000 requests | Limits are applied per account, not per token or OAuth application. All API tokens and OAuth applications under the same account share the same rate limit budget. ## Response headers Every API response includes headers showing your current rate limit status: | Header | Description | | ------------------------------ | ----------------------------------------------------------------- | | `X-RateLimit-Limit-Minute` | Maximum requests allowed per minute | | `X-RateLimit-Remaining-Minute` | Requests remaining in the current minute window | | `X-RateLimit-Reset-Minute` | Unix timestamp when the minute window resets | | `X-RateLimit-Limit-Day` | Maximum requests allowed per day | | `X-RateLimit-Remaining-Day` | Requests remaining in the current day window | | `X-RateLimit-Reset-Day` | Unix timestamp when the day window resets | | `Retry-After` | Seconds to wait before retrying (only present on `429` responses) | ## Handling rate limits When you exceed the limit, the API returns a `429` status code with a `rate_limited` error: ```json theme={null} { "error": { "code": "rate_limited", "message": "Rate limit exceeded" } } ``` Use the `Retry-After` header to determine how long to wait before retrying. ## Best practices * **Check the headers.** Monitor `X-RateLimit-Remaining-Minute` to stay within limits proactively. * **Use filters.** Narrow your `GET /v1/contacts` requests with filters like `email` or `email_consent` to reduce the number of calls needed. * **Cache responses.** Avoid making the same request repeatedly when the data hasn't changed. * **Implement backoff.** If you receive a `429`, wait the number of seconds specified in `Retry-After` before retrying. For repeated failures, use exponential backoff. Need higher limits? Contact [support@privy.com](mailto:support@privy.com) to discuss your use case. # Update a contact Source: https://help.privy.com/docs/api-reference/update-contact openapi/privy-api.yaml PATCH /contacts/{id} Update an existing contact identified by its unique `id`. Include one or more fields to change. Field updates and consent changes can be combined in a single request. Mutable fields: `first_name`, `last_name`, `email`, `phone_number`, `tags`, `custom_fields`. `email` and `phone_number` can only be set when the existing value is `null`. Once populated, they cannot be changed or cleared. Consent fields: `email_consent`, `sms_consent`. Use these to subscribe, unsubscribe, or otherwise manage a contact's marketing consent. When `sms_consent` is set to `subscribed` and the contact transitions to a confirmed opt-in state, Privy automatically sends a TCPA-required welcome SMS. Pass `send_welcome_sms: false` to suppress this message if you have already collected consent outside of Privy. **Required scope:** `contacts_write` # Advanced Flows Source: https://help.privy.com/docs/guides/automations/advanced-automations Take your automated emails to the next level with these content ideas. You've got your Flows set up, and now you want to take them to the next level. Adding more advanced settings to your Flows gives you even more control over the audience you're sending to, which allows you to use more tailored messaging. ## Abandoned Cart Emails ### Settings What settings should I consider to level up my Abandoned Cart strategy? 1. **Cart Value:** You can set a minimum and/or maximum cart value for your series. This would restrict these emails from triggering unless the shopper's cart value meets this criteria. 2. **Products/Collections:** You can select collection(s) or product(s) for your series. This would restrict these emails from triggering unless the shopper's cart contains these items. ### Advanced Content Ideas Below are some possible content ideas that could make your Abandoned Cart Series more pointed and effective for your audience, based on the advanced targeting you selected: * **Tiered discounts:** Consider a tiered abandoned cart strategy, where you offer a certain discount to "low value" carts and another discount to "high value" carts. For example, maybe carts under $75 get 10% off, but carts over $75 get \$10 off. * **Free shipping:** Target carts over your store's free shipping threshold and emphasize that their cart qualifies for free shipping. * **Nice-to-know information:** If you have any certain products or collections that might have great social proof or special information that could motivate a purchase, target these carts and feature this content. * **Customization options:** If you offer any personalization for certain products (i.e., engraving, monograms, custom colors, gift wrapping), target those carts and highlight these services! ## Purchase Follow-Up Emails ### Settings What settings should I consider to level up my post-purchase strategy? 1. **Customer action:** Trigger emails based on a customer placing an order vs. receiving the order. 2. **Order Count:** You can trigger a series for someone's first order, a repeat order, or leave it open-ended to any number of orders. 3. **Order Value:** You can set a minimum and/or maximum order value for this series. This would restrict this series from triggering unless the customer's subtotal met this criteria. 4. **Products/Collections:** You can select collection(s) or product(s) for your series. This would restrict these emails from triggering unless the customer's order contains these items. ### Advanced Content Ideas Below are some possible content ideas that can level up your post-purchase experience, leaving shoppers feeling like they're more than just an order number to you. * **Ask for feedback:** If you don't already use a third party review app, trigger a Purchase Follow-Up email asking customers for a review 30 days post-purchase. * **New customer discount:** Strike while the iron is hot. Use the "First Order" setting under *Order Count* and offer a coupon for new customers to use on their next purchase with you! * **High value = high reward:** Keep your high value customers coming back for more. Use the minimum order value setting and send a personal thank you note from the founder. Include a discount to use on their next big order. * **Care instructions:** Do any of your products/collections require special care or assembly? Let your customers know how to get the most of their purchase. * **Cross sell:** Would a customer benefit from pairing their recent purchase with another product? Let them know a couple weeks after they place their order. Offer a small incentive to encourage repeat buying. ## Things to consider The key to advanced Flows is to identify the moments when you know extra details about your customers. Once you know more about them, use that information to better inform your own content, thus focusing your Flow strategy. You should also be mindful about your own brand and how it operates so that you can set up Flows that feel natural and personal to your audience: * How long does it typically take for your orders to ship/deliver to customers? * How long do your products last? * What's your average order value? This information will help you determine the **timing** and **incentives** to use in your Flows. For example, here's what you want to avoid: Asking for feedback or offering a limited-time discount before your customer even receives their order. Pushing customers to "restock" too soon (i.e., a skincare company might push their next sale before a home improvement store would). Discounting too high for too many customers to decrease your order value. # Flows 101 Source: https://help.privy.com/docs/guides/automations/automations-101 Discover which automated emails are right for your business. In a world where customers are looking for a more personalized shopping experience, automated email flows have never been a more important marketing tool. **A recent study** **showed that automated emails generated 41% of all email orders, while accounting for only 2% of emails sent in 2023.**   Privy’s Flows are set to trigger in response to specific behaviors and key points in a shopper’s journey. This allows you to send the *right communication* at the *right moment*, whether they just signed up with you, forgot about items in their cart, or just completed their first purchase.  When it comes to prioritizing Flows that will make a difference in your email strategy, there are four types that truly stand out: 1. Abandoned Cart Emails 2. Welcome Emails 3. Purchase Follow-Up Emails 4. Customer Winback Emails One of the biggest mistakes you can make with Flows is not having them active at all. Make sure these four series are part of your e-commerce strategy. Otherwise, you're simply leaving money on the table. ## Abandoned Cart Emails Abandoned Cart Emails are one of the most impactful automated series you can activate. By targeting those who came to your site, put something into their cart, and left without completing a purchase, you have the chance to recover the lost sale. **A good Abandoned Cart Series:** Is clear, branded, and contains multiple call-to-actions leading to the recipient's cart. Uses a [Cart Summary](https://help.privy.com/docs/learn/flows/abandoned-cart#build-your-flow) content block to reveal what the recipient left behind. Incentivizes your recipient to complete their purchase. ### Examples [Club Huey](https://clubhuey.com/) does a great job of this on their abandoned cart emails, which includes an incentive to bring them back to their cart. They also show the customer the item that they left behind in their cart, alongside a clear call-to-action: Looking for more Abandoned Cart Email inspiration? [Check out our Swipe File!](https://www.swipewell.app/collections/87de71fd-595b-4aa8-aab2-b00977d62eef) ### Best Practices If you're not sure how to time your series or what kind of content belongs in each email, we put together this formula for you to follow: Not sure how to create an Abandoned Cart Series in Privy? [Here's a step-by-step guide.](https://help.privy.com/docs/learn/flows/abandoned-cart) ## Welcome Emails You only have one chance at a first impression, and when someone first signs up for your list, a [Welcome series](https://help.privy.com/docs/learn/flows/welcome) is the perfect opportunity to introduce your products, shop, and mission. People buy from people, and by establishing trust and a relationship with your audience early on, they’ll be more likely to purchase from you in the future. **A good Welcome Series:** Gets personal and tells your brand's story and mission. Shines a spotlight on your best sellers + brand initiatives. Includes social proof that builds trust and motivates purchases. ### Examples [Capabunga](http://capabunga.com/) has a set up 3 emails where they introduce themselves, showcase their bestsellers, followed by glowing reviews to help build trust. Looking for more Welcome Email inspiration? [Check out our Swipe File!](https://www.swipewell.app/collections/00e7f40c-d33f-4449-8d81-126f1bf1ad93) ### Best Practices Ready to activate your Welcome Series? Here's a great blueprint to start with: Not sure how to create a Welcome Series in Privy? [Here's a step-by-step guide.](https://help.privy.com/docs/learn/flows/welcome) ## Purchase Follow-Up Emails The journey doesn’t end when someone completes their first purchase with you! No one wants to feel like just a transaction, and if you’re only sending out the basic order and shipping confirmation emails, you’re missing out on a big opportunity to make your customers feel special and appreciated. **Some good Purchase Follow-Up ideas include:** A personal thank you note from the founder. Care instructions so that they know how to look after their purchase. Sustainable or philanthropic initiatives that their purchase contributed to. A restock reminder, or a cross sell to promote other products. ### Examples [TePe Oral Health Care](https://www.tepeusa.com/) sends out targeted post-purchase emails based on the product the shopper purchased, providing a custom instructional guide on how to best use the product. Looking for more Purchase Follow-Up inspiration? [Check out our Swipe File!](https://www.swipewell.app/collections/1cf8fbd6-37b2-4809-93cb-74719b247892) ### Best Practices Ready to start with Purchase Follow-Up emails? Here's a great formula to start with: Not sure how to create a Purchase Follow-Up email in Privy? [Here's a step-by-step guide.](https://help.privy.com/docs/learn/flows/purchase-follow-up) ## Customer Winback Emails Did you know that repeat customers created as a result of your actions are 9x more likely to convert, spend 3x your average order value, and are 20% more profitable for your business? That is why customer retention is so important and having an active [Customer Winback series](https://help.privy.com/docs/learn/flows/customer-winback) is crucial. **A good Customer Winback series:** Makes your customer feel noticed and appreciated by [using their first name](https://help.privy.com/docs/learn/content/personalization-tags#using-merge-tags). Creates urgency around an incentive to use on their next order. Is positive and friendly (i.e., "We missed you!"), rather than a sales pitch or guilt trip. ### Examples [Blooms of Hawaii](https://www.bloomsofhawaii.com/) uses a friendly subject line, addresses their customer by their first time, and reminds them of their limited-time incentive in their Winback Series: Looking for more Customer Winback inspiration? [Check out our Swipe File!](https://www.swipewell.app/collections/4230b7e4-367e-4f37-99b3-8482076ae5d7) ### Best Practices If you're not sure how to time your series or what kind of content belongs in each email, we put together this formula for you to follow: Not sure how to create a Customer Winback email in Privy? [Here's a step-by-step guide.](https://help.privy.com/docs/learn/flows/customer-winback) # Flow strategy guides Source: https://help.privy.com/docs/guides/automations/overview Discover best practices and advanced strategies to help you boost engagement and orders. ## The Basics Your customers want a more personalized shopping experience, and you want an email tool that does the heavy lifting for you. Which Flows are right for me? ## Advanced Strategies You’ve got your Flows set up, and now you want to take them to the next level. Learn how to use advanced targeting to tailor your messaging and personalize your content. Turn new customers into repeat buyers, and nurture your relationship with loyal customers. # Build a Strong Post-Purchase Experience Source: https://help.privy.com/docs/guides/automations/post-purchase-experience Use Purchase Follow-Up emails to make your customers feel like more than just an order number. You’ve put a lot of effort into acquiring new leads, turning them into signups, and securing that first order — don’t let it stop there! A customer’s post-purchase period is a crucial time to shape their perception of your brand; are they going to feel like just another transaction, or are they going to feel like a valued customer? The impression you leave behind will have a major effect on whether or not they buy from you again or influence friends, family, or coworkers to try your products. In this guide, we’ll walk you through how to build a solid post-purchase foundation in Privy. ## Welcome New Customers Picture a new customer at your store: what information might be valuable to them? How can you incentivize them to become a repeat customer down the line? In addition to your store’s transactional emails which deliver an order confirmation and shipping information, you should activate a Purchase Follow-Up series which follows this formula: ### Build your series To create a new Purchase Follow-Up series: * Navigate to [Flows](https://dashboard.privy.com/flows) and click **New Flow** in the upper right. * Select Purchase Follow-Up from the following menu. * [Add more emails](https://help.privy.com/docs/learn/flows/purchase-follow-up#add-remove-emails) and [customize your templates.](https://help.privy.com/docs/learn/flows/purchase-follow-up#customize-your-templates) In the series builder, you’ll want to make sure you have the right trigger settings in place: * Click **Edit Settings** on the left side.  * Specify **First Order** in the dropdown menu under *Order Count.* * Offering a discount? Make sure you attach the code under *Coupon* in your settings. * **Save** your settings.