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 Access Token User Attributes API
version: ''
servers:
- url: https://api.attentivemobile.com/v1
description: Attentive API
security:
- bearerAuth: []
tags:
- name: User Attributes
description: 'Endpoints for submitting bulk user attribute updates. Use these endpoints to upload large datasets of user data in a single request and monitor the processing status asynchronously. Typical use cases include importing records in batch and retrieving job completion results via status checks.
## Processing Times
The Bulk API processes jobs with the following targets:
- **Standard Processing**: The first 10,000 user records per day per customer typically complete within 4 hours of request acceptance.
- **High-Volume Processing**: Additional records beyond 10,000 per day typically complete within 12 hours.
**Note**: For jobs with more than 1 million records, processing times may vary.
'
x-beta: true
paths:
/v2/bulk/user/attributes:
x-external: hidden
x-requires-auth: false
post:
x-external: true
x-emits-event: true
security:
- bearerAuth: []
- OAuthFlow:
- attributes:write
- subscriptions:write
summary: Bulk User Attributes
description: 'This endpoint allows clients to submit multiple user attribute updates in bulk, accepting up to 256 payloads per request. Each request is validated, and a unique batch ID is returned for tracking the status of the batch.
Scopes Required: [attributes:all, subscriptions:all]
Default Rate Limit: 100 requests per second
'
operationId: postBulkUserAttributes
parameters:
- name: Authorization
in: header
description: Authorization for the request
required: true
schema:
type: string
tags:
- User Attributes
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UserAttributes'
responses:
'202':
description: 'The bulk job request was successfully received and accepted for asynchronous processing. The response includes a batchJobId to track the status of the job, along with a confirmation message. Processing has not yet completed, please use the job status endpoint to monitor progress and retrieve results once available.
'
content:
application/json:
schema:
$ref: '#/components/schemas/BulkSuccessResponse'
'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:
responses:
InternalError:
description: Internal Server Error
InvalidParameter:
description: Invalid parameter in request query or body
Unauthorized:
description: Unauthorized
NotFound:
description: The specified resource was not found
TooManyRequests:
description: The user has sent too many requests in a given amount of time
AccessDenied:
description: Access Denied
schemas:
CreateUserAttributesRequestDtoV21:
type: object
properties:
attributes:
type: object
description: 'Personal details about the user. These attributes will take priority over custom properties. All fields are considered optional.
'
properties:
firstName:
type: string
description: The user's first name.
example: John
lastName:
type: string
description: The user's last name.
example: Smith
demographic:
type: object
description: An object containing additional personal and professional details.
properties:
language:
type: string
description: The user's preferred language.
example: English/American
dateOfBirth:
type: string
format: date
description: The user's date of birth in YYYY-MM-DD (ISO-8601 format).
example: '2022-11-08'
age:
type: integer
description: The user's age.
example: 29
organization:
type: string
description: The organization the user is associated with.
example: Acme Sports
title:
type: string
description: The user's title (e.g., Mr, Ms, Dr).
example: Mr
website:
type: string
description: The user's website URL.
example: http://johnsmith.com
location:
type: object
description: An object containing the user's address and geographical details.
properties:
address1:
type: string
description: The first line of the address (e.g., street name and number).
example: 456 Elm Avenue
address2:
type: string
description: The second line of the address (e.g., apartment or suite).
example: Suite 300
city:
type: string
description: The city where the user is located.
example: Brooklyn
state:
type: string
description: The state where the user is located.
example: NY
zip:
type: string
description: The postal or ZIP code.
example: '11222'
latitude:
type: string
description: The geographical latitude.
example: '40.730610'
longitude:
type: string
description: The geographical longitude.
example: '-73.935242'
country:
type: string
description: The country of the user provided in ISO-3166-1 format
example: US
region:
type: string
description: The region of the user in ISO-3166-2 format
example: AU-NSW
timezone:
type: string
description: The user's timezone (e.g., EST).
example: EST
locale:
type: object
description: An object representing the user's locale information.
properties:
language:
type: string
description: The preferred language in ISO 639-1 format.
example: French
country:
type: string
description: The user's country in ISO 3166-1 alpha-2 format.
example: CA
custom:
type: object
description: 'A key-value object for custom attributes. Please use the correct primitive type for the value. DateTime strings must adhere to ISO-8601 format for proper recognition.
The key will be assigned a type corresponding to the type seen of the first value. For example, if ''Age'' is passed with the first value of ''24'', ''Age'' will be typed as a ''Number''. There is no need to pass strings in double quotes. Both object keys and object values are case sensitive. "Favorite color" and "Favorite Color" would be considered different custom attributes.
'
additionalProperties: {}
example:
lucky number: 6
favorite color: green
has pets: true
subscriptions:
type: array
description: "An array of subscription details, defining how the user prefers to receive communications.\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 - 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 may result in a message being sent to the person indicating that they are already subscribed.\n- Requests to opt-in subscribers must contain a sign-up source id.\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). 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.\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"
items:
type: object
properties:
signUpSourceId:
type: string
description: A string identifying the source of the user's sign-up.
example: string
channel:
type: string
description: "The communication channel the user is subscribed to (e.g., TEXT). Supported channels include:\n - TEXT\n - EMAIL\n"
example: TEXT
enum:
- TEXT
- EMAIL
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"
example: true
required:
- signUpSourceId
- channel
- subscriptionType
identifiers:
type: object
description: 'Contains various identifiers used to uniquely identify the user.
Notes:
- Sending duplicate values could lead to unintentionally bridging users together.
- Don''t use customIdentifiers to send attributes (e.g., first name, last name). To send those types of attributes, add to the attributes payload.
- Avoid sending null values or empty strings. If you don''t have a valid identifier, you should omit the field from the payload.
'
minProperties: 1
properties:
email:
type: string
description: The user's email address.
example: jsmith@attentive.com
phone:
type: string
description: The user's phone number.
example: '+15008675309'
shopifyId:
type: string
description: The user's Shopify ID, if applicable.
example: '345678901'
klaviyoId:
type: string
description: The user's Klaviyo ID, if applicable.
example: a1b2c3d4e5f6a7b8c9d0e1f2
clientUserId:
type: string
description: 'Your own unique identifier to be associated with a user to be associated with a user through a phone, email, shopify id, klaviyo id, or custom identifier. Please do NOT put Shopify IDs or Klaviyo IDs here, there are dedicated fields for those identifiers. There is a 100-character limit.
'
example: freeform-client-id
customIdentifiers:
type: array
items:
$ref: '#/components/schemas/CustomIdentifier'
UserAttributes:
properties:
users:
type: array
description: Array of user attribute records to submit (up to 256 users).
minItems: 1
maxItems: 256
items:
$ref: '#/components/schemas/CreateUserAttributesRequestDtoV21'
BulkSuccessResponse:
type: object
properties:
message:
type: string
description: 'A human-readable message confirming that the bulk job was successfully submitted.
'
batchJobId:
type: string
description: 'A unique identifier representing the submitted batch job. Use this ID to query the job''s status, retrieve results, or diagnose any errors related to the job. This ID is returned upon successful job submission and required for all follow-up actions related to the batch.
'
CustomIdentifier:
type: object
description: 'An object containing custom identifiers to associate with an incoming user
'
properties:
key:
type: string
description: The name of the custom identifier.
example: loyalty_points_id
value:
type: string
description: The value of the custom identifier.
example: ADFK4D7D
required:
- key
- value
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
x-readme:
explorer-enabled: false