---
updatedAt: 2026-04-20T23:50:10.000Z
agentTools:
  projectIndex: https://docs.attentive.com/llms.txt
---

# Subscribe user

Make a call to this endpoint to opt-in a user to a subscription. 

Notes:
- A legal disclosure is required when a user is opted-in programmatically.
    - For marketing messages, required [legal language](https://docs.attentivemobile.com/pages/legal-docs/legal-disclosure-language/) must be included.

    - For transactional messages, you must include a [transactional opt-in unit](https://docs.attentivemobile.com/pages/legal-docs/legal-transactional/).
  
- By default, if a subscription already exists, it will try and record the attempt to create the subscription again. For TEXT subscriptions, this will result in a message being sent to the person indicating that they are already subscribed.
- Requests to opt-in subscribers must either contain a) a sign-up source id or b) both a locale and a subscription type.
    - The unique identifier of a sign-up source can be found in the Sign-up Units tab of the Attentive platform in the ID column. 
    If this value is provided in the request, then this sign-up unit will be used for opting in the user in the request.

    - Callers of this endpoint have the option to omit `signUpSourceId` and, instead, provide both a `locale` and a `subscriptionType` (see below for field details). 
    Given the locale and subscription type, Attentive will resolve any matching API opt-in units. To opt-in a user to a subscription without a `signUpSourceId` and exclusively based on locale and subscription type,
    there must be exactly one API sign-up unit that matches the provided locale and subscription type. Conversely, requests that contain a locale and a subscription type
    that do not have a corresponding sign-up unit or that have multiple matching sign-up units will receive a `400` response and will not opt a user into a subscription.

- For users in either France or Italy, in accordance with compliance updates documented [here](https://help.attentive.com/hc/en-us/articles/51464632390804-France-Email-Privacy-Compliance-Update), we set an email pixel tracking
  consent attribute as part of opting in an email subscriber. This is set by default when the locale of a subscriber is in France or Italy.
  We expose the capability in this endpoint to set this consent on behalf of the user via the `pixelTrackingConsent` parameter. This is a boolean parameter which when provided indicates whether or not a subscriber has consented
  to email pixel tracking. When this endpoint is called with `pixelTrackingConsent = true` and an email on the `UserDto`, the email subscription will be created with that tracking consent, visible in subscriber attributes. If 
  it is not passed in at all the consent defaults to false.
  NOTE: This parameter will only be honored if it is passed in with a `signUpSourceId`, otherwise we will not save the attribute.

- Phone numbers must be submitted in [e164 format](https://en.wikipedia.org/wiki/E.164).
    - valid examples: `+19148440001`, `+442071838750`, `+551155256325`
    - invalid examples: `19148440001`, `+1---914---844---0001`, `1 () 914 844 0001`


# OpenAPI definition

```json
{
  "openapi": "3.0.3",
  "info": {
    "description": "For any questions, reach out to your Attentive point of contact (if applicable) or [api@attentivemobile.com](mailto:api@attentivemobile.com).",
    "title": "Attentive API",
    "version": ""
  },
  "servers": [
    {
      "url": "https://api.attentivemobile.com/v1",
      "description": "Attentive API"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Subscribers",
      "description": "Use the Subscribers API to manage subscriptions. With this API, you can programmatically subscribe and unsubscribe users from subscriptions.\n",
      "x-beta": false
    }
  ],
  "paths": {
    "/subscriptions": {
      "post": {
        "x-external": true,
        "x-emits-event": true,
        "security": [
          {
            "OAuthFlow": [
              "subscriptions:write"
            ]
          }
        ],
        "summary": "Subscribe user",
        "description": "Make a call to this endpoint to opt-in a user to a subscription. \n\nNotes:\n- A legal disclosure is required when a user is opted-in programmatically.\n    - For marketing messages, required [legal language](https://docs.attentivemobile.com/pages/legal-docs/legal-disclosure-language/) must be included.\n\n    - For transactional messages, you must include a [transactional opt-in unit](https://docs.attentivemobile.com/pages/legal-docs/legal-transactional/).\n  \n- By default, if a subscription already exists, it will try and record the attempt to create the subscription again. For TEXT subscriptions, this will result in a message being sent to the person indicating that they are already subscribed.\n- Requests to opt-in subscribers must either contain a) a sign-up source id or b) both a locale and a subscription type.\n    - The unique identifier of a sign-up source can be found in the Sign-up Units tab of the Attentive platform in the ID column. \n    If this value is provided in the request, then this sign-up unit will be used for opting in the user in the request.\n\n    - Callers of this endpoint have the option to omit `signUpSourceId` and, instead, provide both a `locale` and a `subscriptionType` (see below for field details). \n    Given the locale and subscription type, Attentive will resolve any matching API opt-in units. To opt-in a user to a subscription without a `signUpSourceId` and exclusively based on locale and subscription type,\n    there must be exactly one API sign-up unit that matches the provided locale and subscription type. Conversely, requests that contain a locale and a subscription type\n    that do not have a corresponding sign-up unit or that have multiple matching sign-up units will receive a `400` response and will not opt a user into a subscription.\n\n- For users in either France or Italy, in accordance with compliance updates documented [here](https://help.attentive.com/hc/en-us/articles/51464632390804-France-Email-Privacy-Compliance-Update), we set an email pixel tracking\n  consent attribute as part of opting in an email subscriber. This is set by default when the locale of a subscriber is in France or Italy.\n  We expose the capability in this endpoint to set this consent on behalf of the user via the `pixelTrackingConsent` parameter. This is a boolean parameter which when provided indicates whether or not a subscriber has consented\n  to email pixel tracking. When this endpoint is called with `pixelTrackingConsent = true` and an email on the `UserDto`, the email subscription will be created with that tracking consent, visible in subscriber attributes. If \n  it is not passed in at all the consent defaults to false.\n  NOTE: This parameter will only be honored if it is passed in with a `signUpSourceId`, otherwise we will not save the attribute.\n\n- Phone numbers must be submitted in [e164 format](https://en.wikipedia.org/wiki/E.164).\n    - valid examples: `+19148440001`, `+442071838750`, `+551155256325`\n    - invalid examples: `19148440001`, `+1---914---844---0001`, `1 () 914 844 0001`\n",
        "operationId": "addSubscriptions",
        "tags": [
          "Subscribers"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddSubscriptionsRequestDto"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted a create subscription(s) request. The response body will contain info about which subscription(s) already exist, and which subscription(s) will be created (asynchronously).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddSubscriptionsResponseDto"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidParameter"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/AccessDenied"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "OAuthFlow": {
        "type": "oauth2",
        "description": "This API uses OAuth 2 with the authorization code grant flow. [More info](https://docs.attentivemobile.com/pages/authentication/)",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://ui-devel.attentivemobile.com/integrations/oauth-install?client_id={clientId}&redirect_uri={redirectUri}&scope={scope}",
            "tokenUrl": "https://api.attentivemobile.com/v1/authorization-codes/tokens",
            "scopes": {
              "attributes:write": "read and write custom attributes",
              "subscriptions:write": "read and write subscriptions",
              "events:write": "read and write custom events",
              "ecommerce:write": "read and write ecommerce events",
              "segments:write": "read and write segments",
              "segments:read": "read segments"
            }
          }
        }
      }
    },
    "schemas": {
      "AddSubscriptionsRequestDto": {
        "type": "object",
        "properties": {
          "user": {
            "$ref": "#/components/schemas/UserDto1"
          },
          "signUpSourceId": {
            "type": "string",
            "description": "The unique identifier of the sign-up source. This can be found in the Sign-up Units tab of the Attentive platform in the ID column for any API sign-up method.\nThis field is required if locale is not present. \n\nOr, you can contact our White Glove team (whiteglove@attentivemobile.com)\nor your Client Strategy Manager at Attentive to request a sign-up source for either marketing or\ntransactional opt-ins. Our team will review API opt-in units with\n[compliance in mind](https://docs.attentivemobile.com/pages/legal-docs/legal-disclosure-language/).\n"
          },
          "externalIdentifiers": {
            "$ref": "#/components/schemas/NewExternalIdentifierDto"
          },
          "locale": {
            "$ref": "#/components/schemas/LocaleDto"
          },
          "subscriptionType": {
            "type": "string",
            "enum": [
              "MARKETING",
              "TRANSACTIONAL"
            ]
          },
          "singleOptIn": {
            "type": "boolean",
            "description": "Opt in subscriber silently (do not send a Reply Y to subscribe text).\n\nNOTE: This property is disabled (set to false) by default. We strongly recommend maintaining the standard \ndouble opt-in flow, as it serves important legal and compliance purposes. If you want to enable single opt-in, \nwe encourage you to speak with your dedicated Client Strategy Manager (CSM) or our White Glove team \n(whiteglove@attentivemobile.com) before you enable it. If this property is set to true, subscribers will be \nadded without receiving the initial “Reply Y” confirmation text message. This setting bypasses only the \n“Reply Y” message. The mandatory legal message will still be sent.\n"
          },
          "pixelTrackingConsent": {
            "type": "boolean",
            "description": "Explicitly set subscriber pixel tracking consent. This is implemented in accordance with compliance requirements\nin France and Italy. French and Italian subscribers have to explicitly opt in to email pixel tracking, so this\nparameter allows third party developers to create a subscription with the tracking consent set.\n\nNOTE: This property is false by default. Will only be set to true if explicitly passed in. It will also only \nbe honored if it is passed in alongside a signupSourceId.\n"
          }
        },
        "required": [
          "user"
        ]
      },
      "AddSubscriptionsResponseDto": {
        "type": "object",
        "properties": {
          "user": {
            "$ref": "#/components/schemas/UserDto1"
          },
          "externalIdentifiers": {
            "$ref": "#/components/schemas/NewExternalIdentifierDto"
          },
          "subscriptionResponses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AddSubscriptionResponseDto"
            }
          }
        }
      },
      "UserDto1": {
        "type": "object",
        "description": "User associated with the action. Note that this is a visitor to the site and does not need to be actively subscribed to Attentive.",
        "properties": {
          "phone": {
            "type": "string",
            "description": "Phone number of the user associated with the action. [E.164 format](https://en.wikipedia.org/wiki/E.164) is required. This field is required if email is not provided.",
            "example": "+13115552368"
          },
          "email": {
            "type": "string",
            "description": "Email of the user associated with the action. This field is required if phone is not provided.",
            "example": "test@gmail.com"
          }
        }
      },
      "LocaleDto": {
        "type": "object",
        "properties": {
          "language": {
            "type": "string",
            "description": "Two-letter language code of the locale. [ISO 639-1 alpha 2](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) is required. Values are case sensitive and must match exactly.",
            "example": "en"
          },
          "country": {
            "type": "string",
            "description": "Two-letter country code of the locale. [ISO-3166-1 alpha 2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) is required. Values are case sensitive and must match exactly.",
            "example": "US"
          }
        }
      },
      "SubscriptionDto": {
        "type": "object",
        "description": "A type and channel combination.",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "MARKETING",
              "TRANSACTIONAL",
              "CHECKOUT_ABANDONED",
              "CONTACT"
            ]
          },
          "channel": {
            "type": "string",
            "enum": [
              "TEXT",
              "EMAIL"
            ]
          }
        }
      },
      "CustomIdentifierDto": {
        "type": "object",
        "description": "Namespaced custom identifier and value",
        "properties": {
          "name": {
            "type": "string"
          },
          "value": {
            "type": "string"
          }
        }
      },
      "SubscriptionCreationStatus": {
        "type": "string",
        "enum": [
          "NEWLY_CREATED",
          "PREVIOUSLY_CREATED"
        ]
      },
      "AddSubscriptionResponseDto": {
        "type": "object",
        "description": "A subscription and a status indicating whether the subscription for this particular user was newly created or was previously created (i.e. already existed)",
        "properties": {
          "subscription": {
            "$ref": "#/components/schemas/SubscriptionDto"
          },
          "subscriptionCreationStatus": {
            "$ref": "#/components/schemas/SubscriptionCreationStatus"
          }
        }
      },
      "NewExternalIdentifierDto": {
        "type": "object",
        "description": "External Identifiers for a user",
        "properties": {
          "clientUserId": {
            "type": "string",
            "description": "Notes:\nSending duplicate values could lead to unintentionally bridging users together.\nDon't use customIdentifiers to send attributes (e.g., first name, last name). To send those types of attributes, use our Custom Attributes API.\nAvoid sending null values or empty strings. If you don't have a valid identifier, you should omit the field from the payload.\n"
          },
          "shopifyId": {
            "type": "string",
            "description": "Notes:\nSending duplicate values could lead to unintentionally bridging users together.\nDon't use customIdentifiers to send attributes (e.g., first name, last name). To send those types of attributes, use our Custom Attributes API.\nAvoid sending null values or empty strings. If you don't have a valid identifier, you should omit the field from the payload.\n"
          },
          "klaviyoId": {
            "type": "string",
            "description": "Notes:\nSending duplicate values could lead to unintentionally bridging users together.\nDon't use customIdentifiers to send attributes (e.g., first name, last name). To send those types of attributes, use our Custom Attributes API.\nAvoid sending null values or empty strings. If you don't have a valid identifier, you should omit the field from the payload.\n"
          },
          "customIdentifiers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomIdentifierDto"
            }
          }
        }
      }
    },
    "responses": {
      "NotFound": {
        "description": "The specified resource was not found"
      },
      "AccessDenied": {
        "description": "Access Denied"
      },
      "InvalidParameter": {
        "description": "Invalid parameter in request query or body"
      },
      "InternalError": {
        "description": "Internal Server Error"
      },
      "Unauthorized": {
        "description": "Unauthorized"
      },
      "TooManyRequests": {
        "description": "The user has sent too many requests in a given amount of time"
      }
    }
  },
  "x-readme": {
    "explorer-enabled": false
  }
}
```