Use the Connect GraphQL API to send behavioral signals from your backend or other external systems in near real time. In Connect, this is the API call method under Signal management > Add signal. Signals you send this way are processed just like signals from the Connect library.
You can use external signals on their own without integrating our library into your application or as an addition to native Connect signals. This is useful for merging signals from multiple sources when the Connect library doesn't have access to parts of the user journey that rely on third-party components (payment processors, ticket management solutions, etc.).
Note:pageView can also be generated automatically by the SDK from screen-view activity, independent of this API. See Page view signals for details on inferred signals.Requirements
Requirements
Contact mapping
Each signal must map to a contact. Use the audience object to provide a contact key or an addressable attribute (email or phone number). You can provide several identification records in the same call — for example, a contact key and an email address. For details on how Connect processes identification records, see How signals update data in your Connect subscription.
Batch size
Maximum 500 signals per mutation
Before you begin
Get your application key (it maps imported signals to an application).
- Connect Pro: Key provided during onboarding
- Connect Premium and Ultimate: Generate through Connect interface (see Get an application key for the Connect library)
Running the mutation
If you haven't used our API before, see Using the Connect API for instructions. It explains how to authenticate your calls and suggests some tools for testing.
Mutation arguments
signals (required): Array of objects - Create an object for each signal you want to import. See Signal object below.
Signal object
appKey(required): String - Your application identifier in Connectaudience(required): Array of objects - Create an object for contact mapping and any number of additional objects to update contact attributes.consent: Object - Consent preferences to update for the contact. At least one of the following channel fields is required:email,smsorwhatsapp.- products: Array of arrays - Products to create or update in your product catalog, for any signal type. See the products object below.
sessionId: String - Session ID for grouping signals from the same contactsignalContent(required): JSON object - Signal contenttest: Boolean - Flag for importing test signals (default:false). For details, the How it works section at the bottom.
Audience object
Create an object with one or more identifiers for contact mapping (required) and any number of additional objects for other contact attributes you want to update.
name(required): String - Name of contact attribute as it appears in Connect (case sensitive). To get the full list of available attributes, use the Contact attributes query.value: The new value of the contact attribute. Its format depends on the attribute type (text, number, Boolean or date). If you send an empty or null value, it will be ignored and the contact attribute won't be updated.
Notes on supported values
- For date attributes, use the following format:
yyyy-MM-dd'T'HH:mm:ssXXX.- For phone number attributes, use the ISO E.164 format:
+[country code][area code][phone number]— no spaces, dashes or special characters. If the+symbol is omitted, Connect adds it automatically.
Consent object
Each channel accepts multiple entries to set different consent statuses per consent group in a single call.
enableOverrideExistingOptOut(required): Boolean - Whentrue, current opt-out statuses will be overridden by new statuses. Whenfalse, contacts who have unsubscribed from communications won't have their consent status updated.email: Array of objects - Consent entries for the email channel. The objects support the following fields:status(required): Enum - Consent status for the email channel. Valid values:OPT_IN,OPT_OUT,OPT_IN_UNVERIFIED.consentGroupIds: Array of strings - The IDs of consent groups a new status applies to. If you skip this field or send an empty array, the new consent status will be applied to all consent groups.
sms: Array of objects - Consent entries for the SMS channel. The objects support the following fields:status(required): Enum - Consent status for the SMS channel. Valid values:OPT_IN,OPT_OUT,OPT_IN_UNVERIFIED.consentGroupIds: Array of strings - The IDs of consent groups a new status applies to. If you skip this field or send an empty array, the new consent status will be applied to all consent groups.
whatsapp: Array of objects - Consent entries for the WhatsApp channel. The objects support the following fields:status(required): Enum - Consent status for the WhatsApp channel. Valid values:OPT_IN,OPT_OUT,OPT_IN_UNVERIFIED.consentGroupIds: Array of strings - The IDs of consent groups a new status applies to. If you skip this field or send an empty array, the new consent status will be applied to all consent groups.
Products object
Use products to create or update product catalog records from any signal, whatever its signalType. For example, a page view or an error signal can also keep your catalog in sync, without a separate call.
- The outer array holds one entry per product.
- Each product is an array of attribute objects (
ProductAttributeSignalInputin the schema):name(required): String - Name of the product attribute, for exampleproductId,productNameorunitPrice.value: Value of the attribute. Accepted types: text, number, Boolean, date (ISO 8601 string), JSON object, or an array of text, number, Boolean and date values. Null values are ignored.
- Each product needs exactly one
productIdattribute. A product without a validproductIdis skipped; the rest of the signal is still processed and no error is returned.
mutation {
createSignals(
signals: [
{
appKey: "{YOUR_APP_KEY}"
audience: [
{ name: "Customer ID", value: "AAUN-1417508" }
]
signalContent: {
signalType: "pageView"
url: "https://www.example.com/painting-and-decorating/paint"
}
products: [
[
{ name: "productId", value: "AC-PNT-WHT-SM" }
{ name: "productName", value: "AWESOME COLORS Interior Paint Satin Finish 32 Fl Oz" }
{ name: "unitPrice", value: 39.99 }
]
[
{ name: "productId", value: "AC-DBL-BRSH-6" }
{ name: "productName", value: "AWESOME COLORS Double Thick Chip Paint Brush" }
{ name: "unitPrice", value: 9.49 }
]
]
}
]
) {
signalIds
}
}| If you send | What happens |
|---|---|
No products, or null, or an empty array | No catalog update from products. Product view, add-to-cart, product configuration and order signals still update the catalog from their own product fields. |
An empty product ([]) | That entry is ignored. |
A product without a valid productId | That product is skipped. The signal and the other products are processed, and no error is returned. |
products on an order signal | The catalog is updated from products only; orderedItems isn't used for the catalog. The order itself is recorded as usual. |
Signal content object
The structure of the signalContent object depends on the type of signal you are importing.
Each signal type has its own page with an example mutation and its fields:
Response fields
The mutation returns a JSON response containing:
data: Object - The root data object containing the mutation resultscreateSignals: Object - Contains the results of the signal creation operationsignalIds: Array of strings - UUIDs for each successfully imported signal (share with support for troubleshooting)
Verification methods
Method 1: Contact details
- Log in to Acoustic Connect.
- Navigate to Data management > Audience.
- Select contact from All contacts tab.
- Find signals in activity feed.

Notes:
- Activity feed shows 5 most recent signals per session (identification signal not displayed)
- Displays last 1000 signals or signals from last 30 days
- Newly added signals may not be immediately visible
Method 2: Signal management
- Navigate to Behavioral management > Signal management.
- View all signal types supported by your subscription.
- Click on signal types to see details.

Method 3: Sessions (Connect Ultimate only)
For Ultimate subscriptions with replay-able sessions generated by Connect library:
- Navigate to Insights > Sessions > Session search.
- Find session by ID and select it.
- Click Inspect signals.
- Review imported signal content.

How it works
Required vs. optional fields
- If any required field is missing or invalid, the entire signal is discarded.
- Optional fields enhance the signal but don't prevent processing if omitted or invalid. However, if you add optional arrays such as
orderedItemsfor the order signal, they must contain all required fields.
Test signals
When test is set to true:
- Signals go through standard validation
- No impact on campaigns
- Not visible in Activity feed, Segmentation or Insights
Validation
In the current implementation, signal import is asynchronous. Connect validates the audience data after a mutation is sent. So if the name of an optional attribute is misspelled, it will be ignored. If an identification record is invalid, the whole signal gets discarded.
Session ID behavior
When you provide a sessionId:
- System registers the session as if generated by Connect library.
- Signals are included in aggregate reports and in-market interest calculation.
- System appends a timestamp to ensure uniqueness (e.g.,
OOII97671461Jgfa9999becomesOOII97671461Jgfa9999.1751479037630).
When you skip sessionId:
- Signals appear in contacts' Activity feed.
- Signals aren't used for aggregate reports.
