- Applies to: Sprinklr Customer Feedback Management (CFM) Transaction APIs V3 (
/api/v3/surveyTransactions) - V2 API reference: CFM Transaction APIs | Sprinklr Developer Portal
A transaction is a CFM-specific record that documents a single customer interaction at a specific moment in time — a purchase, a refund, a service visit, a support contact, or a loyalty redemption. Transactions are contained within a user profile and carry a unique set of metadata stored as key-value pairs in Transaction Fields. Because each interaction is stored independently rather than overwriting the profile, a customer who shops twice produces two transactions, and each one can drive its own survey distribution.
Transactions are grouped into Transaction Groups: a named set of transactions created in the CFM Persona App under Audience Management → Transaction. Survey workflows subscribe to one or more transaction groups, and a Transaction Record Event workflow fires every time a new transaction is ingested into a subscribed group.
The CFM Transaction APIs V3 expose three operations on a single resource path — /api/v3/surveyTransactions — differentiated by HTTP method:
| Operation | Method | Path | operationId |
|---|---|---|---|
| Create transactions in a group | POST | /api/v3/surveyTransactions | SurveyTransactionApiV3_createTransactions |
| Fetch a transaction by ID | GET | /api/v3/surveyTransactions?id= | SurveyTransactionApiV3_getTransaction |
| Delete a transaction | DELETE | /api/v3/surveyTransactions?id= | SurveyTransactionApiV3_deleteTransaction |
This single-path, method-differentiated shape is the central design change in V3 and matches the pattern already used by Profile V3 (/api/v3/profile) and Survey Response V3.
There is no bulk list operation on /api/v3/surveyTransactions. GET returns exactly one transaction, addressed by its ID. To enumerate every transaction in a group, use the Search by Entity API.
The Transaction schema in sprinklr-v3.yaml is the single object used both as the request array element on POST and as the response payload on GET.
| Layer | Fields | What it holds |
|---|---|---|
| Identity | id, userId, profileName | The Sprinklr transaction ID, the profile identifier the transaction attaches to, and the display name |
| Grouping | transactionGroupId, transactionGroupType | The group the transaction lives in, and the group's ingestion type |
| Distribution | distributionChannel | The channel the survey invitation is sent on |
| Metadata | customProperties | Arbitrary key-value interaction metadata, mapped to Transaction Fields |
| Lifecycle | isArchived, deleted, canEdit, ownerUserId, lastModifiedUserId, createdTime | Ownership, audit, and state flags returned by the platform |
| Access control | assetPermission | Asset-level permission object |
A transaction is addressed one way only: by its Sprinklr transaction ID, returned in data[].id on create — for example 6a88545dd4bb4391d3760b0b. There is no alternate business key. Persist the ID returned by POST if you intend to fetch or delete the record later.
Three things must exist before the first API call succeeds.
- CFM must be enabled in your environment. Per the Sprinklr Developer Portal: "CFM must be enabled in your environment before you can utilize these APIs. Please contact your Success Manager for more details."
- A user profile must exist for the
userId. A transaction attaches to a profile. If no profile exists for the identifier you send, create one first with the Create Profile API (see the Profile API V3 developer guide). Sprinklr's file-import path creates a profile automatically when one is absent; the supplied endpoint specification forPOST /surveyTransactionsstates the profile is a prerequisite for the API path. - A transaction group must exist, and it must be of type
API. Create it in the CFM Persona App under Audience Management → Transaction → Create Transaction Group. Per the Help Center: "If you plan to send transactions programmatically from an external system in real time, create a Transaction Group of type API, and setup the API." Share the group with the survey projects where the workflow will run — only shared groups are selectable inside workflows. Transactions can only be created inside an existing group; the API does not create groups.
All API calls are sent to the production endpoint:
https://api3.sprinklr.com/{env}/api/v3So the transaction resource in production is:
https://api3.sprinklr.com/{env}/api/v3/surveyTransactionsReplace {env} with your assigned environment identifier (prod0, prod2, prod3, prod4, prod5, prod6, prod8, prod11, prod12, prod15–prod19, prod21, prod24, production, spr-uat, azrqa — see APIs | Sprinklr Developer Portal for the authoritative list).
All CFM Transaction API calls are authenticated with OAuth 2.0. See API Overview for portal registration, API key and secret generation, and the Authorize flow.
| Header | Value | Purpose | Required on |
|---|---|---|---|
Authorization | Bearer {{accessToken}} | Authenticates the user with the server | All requests |
Key | {{apiKey}} | Authenticates the application with the server | All requests |
Content-Type | application/json | Declares the request body media type | POST |
Accept | application/json | Declares the acceptable response type | All requests |
Adds one or more transactions to an existing transaction group. Each transaction represents a single interaction record for a user.
POST /api/v3/surveyTransactionsRequest schema: SurveyTransactionsCreateRequestDTO — "Create survey transactions in a transaction group." Required: transactionGroupId, transactions
| Parameter | Type | Required | Description |
|---|---|---|---|
transactionGroupId | String | Yes | The unique identifier of the transaction group in which the transactions are created. Create the transaction group in your CFM Persona App before calling this API. |
transactions | Array of Transaction | Yes | The list of transactions to be processed. |
transactions[].userId | String | Yes | The identifier of the user profile the transaction attaches to — typically an email address, mobile number, or unique reference ID. A profile must already exist for this value. |
transactions[].profileName | String | No | The display name associated with the profile. |
transactions[].distributionChannel | String | Yes | The channel used to distribute the survey invitation, for example EMAIL. See §9. |
transactions[].customProperties | Object | No | Free-form interaction metadata as key-value pairs, mapped to the Transaction Fields configured for the group. |
customProperties.orderId | String | No | Example custom property — the order identifier for the interaction. |
customProperties.purchaseAmount | String | No | Example custom property — the transaction amount. |
customProperties.purchaseCategory | String | No | Example custom property — the product or service category. |
orderId, purchaseAmount, and purchaseCategory are illustrative custom properties taken from the supplied specification. They are not fixed fields. The keys your group accepts are the Transaction Fields configured for it under Global Settings → Transaction Fields.
curl --location 'https://api3.sprinklr.com/{env}/api/v3/surveyTransactions' \
--header 'Authorization: Bearer {{accessToken}}' \
--header 'Key: {{apiKey}}' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"transactionGroupId": "68adc96c444bb074f1fd28f7",
"transactions": [
{
"userId": "jordan.rivera@example.com",
"profileName": "Jordan Rivera",
"distributionChannel": "EMAIL",
"customProperties": {
"orderId": "ORD-40219",
"purchaseAmount": "129.00",
"purchaseCategory": "Footwear"
}
}
]
}'{
"data": [
{
"id": "6a88545dd4bb4391d3760b0b",
"userId": "jordan.rivera@example.com",
"profileName": "Jordan Rivera",
"transactionGroupId": "68adc96c444bb074f1fd28f7",
"distributionChannel": "EMAIL",
"customProperties": {},
"isArchived": false,
"ownerUserId": 66009896,
"createdTime": "Aug 21, 2026, 01:36:29 PM",
"lastModifiedUserId": 66009896,
"deleted": false,
"canEdit": false
}
],
"errors": []
}Illustrative response, reproduced from the supplied specification with the user identifier replaced by a placeholder. No API call was executed to produce it.
Note that data is an array on create — one element per transaction submitted, in request order — whereas GET returns a single object. Read data[].id and persist it.
In the supplied sample,
customPropertiesis returned as an empty object even though the request could carry properties, because the sample request had its properties commented out. WhethercustomPropertiesis echoed back on create is unconfirmed.
| Parameter | Type | Description |
|---|---|---|
data | Array | The list of transactions created. |
data[].id | String | The unique identifier of the created transaction. |
data[].userId | String | The profile identifier the transaction is attached to. |
data[].profileName | String | The display name associated with the profile. |
data[].transactionGroupId | String | The identifier of the transaction group containing the transaction. |
data[].distributionChannel | String | The channel used to distribute the survey invitation. |
data[].customProperties | Object | The interaction metadata stored against the transaction. |
data[].isArchived | Boolean | Indicates whether the transaction is archived. |
data[].ownerUserId | Long | The Sprinklr user ID of the transaction owner. |
data[].createdTime | String | The creation timestamp of the transaction. |
data[].lastModifiedUserId | Long | The Sprinklr user ID of the last user to modify the transaction. |
data[].deleted | Boolean | Indicates whether the transaction is deleted. |
data[].canEdit | Boolean | Indicates whether the caller can edit the transaction. |
errors | Array | The list of errors. Empty on success. |
Retrieves detailed information about a specific transaction using its unique transaction ID. Use it to validate and review transaction attributes, including user details, distribution channel, and status.
GET /api/v3/surveyTransactions?id={transactionId}Response schema: Transaction
| Parameter | In | Type | Required (spec) | Description |
|---|---|---|---|---|
id | query | String | required: false in the OpenAPI specification; Required in the supplied endpoint specification | The unique identifier of the survey transaction to retrieve. |
curl --location 'https://api3.sprinklr.com/{env}/api/v3/surveyTransactions?id=6a8c446a69baf80612fb63f7' \
--header 'Authorization: Bearer {{accessToken}}' \
--header 'Key: {{apiKey}}' \
--header 'Accept: application/json'{
"data": {
"id": "6a8c446a69baf80612fb63f7",
"userId": "jordan.rivera@example.com",
"profileName": "Jordan Rivera",
"transactionGroupId": "68adc96c444bb074f1fd28f7",
"distributionChannel": "EMAIL",
"customProperties": {},
"isArchived": false,
"ownerUserId": 66009896,
"createdTime": "Aug 24, 2026, 01:17:30 PM",
"lastModifiedUserId": 66009896,
"deleted": false,
"canEdit": false
},
"errors": []
}Illustrative response, reproduced from the supplied specification with the user identifier replaced by a placeholder.
The response parameters are identical to those in §4.4, except that data is a single object rather than an array.
There is no bulk-list operation on /api/v3/surveyTransactions. To fetch all transactions in a transaction group:
- Call the Search by Entity API with
TRANSACTIONas theentityTypeandtransactionGroupIdin thefiltersobject. - Read the
cursorreturned in the response. - Pass that
cursorto the Search by Cursor API to retrieve the next page, and repeat until the cursor is exhausted.
Specification gap. The supplied specification names these two APIs but does not give their paths, request schemas, or the exact
filterssyntax fortransactionGroupId. The guide cannot document the call without inventing it.
Deletes a specific transaction using its unique transaction ID.
DELETE /api/v3/surveyTransactions?id={transactionId}| Parameter | In | Type | Required (spec) | Description |
|---|---|---|---|---|
id | query | String | required: false in the OpenAPI specification; Required in the supplied endpoint specification | The unique identifier of the survey transaction to delete. |
transactionGroupId | query | String | Undocumented | Appears in the supplied cURL sample only. Not declared in the OpenAPI specification and not present in any parameter table. |
curl --request DELETE 'https://api3.sprinklr.com/{env}/api/v3/surveyTransactions?id=6a5e22a5155ab63b8b142d7c' \
--header 'Authorization: Bearer {{accessToken}}' \
--header 'Key: {{apiKey}}' \
--header 'Accept: application/json'The three sources disagree on what DELETE returns.
| Source | Declared response |
|---|---|
sprinklr-v3.yaml | 200 Success, application/json, schema: {type: string} |
| Supplied specification — "Example Response" | HTTP/1.1 204 (No Content) |
| Supplied specification — parameter table | A JSON envelope: data (String) "Indicates whether the survey transaction was successfully deleted", errors (Array) |
Documented on the assumption the envelope form is correct:
| Parameter | Type | Description |
|---|---|---|
data | String | Indicates whether the survey transaction was successfully deleted. |
errors | Array | The list of errors. Empty on success. |
All CFM Transaction V3 responses use the standard APIResponse envelope declared in `sprinklr-v3:
| Field | Type | Description |
|---|---|---|
data | Object or Array | The operation payload. An array of Transaction on POST; a single Transaction on GET; a String on DELETE |
errors | Array of Error | The list of errors. Empty on success. |
metadata | ResponseMetadata | Response metadata. |
| Code | Meaning | Typical cause |
|---|---|---|
200 | Success | The request was processed. Inspect errors before assuming a complete success on POST. |
400 | Bad Request | Malformed JSON, a missing required field (transactionGroupId or transactions), a missing userId or distributionChannel, or an unrecognised customProperties key. |
401 | Unauthorized | Missing, expired, or invalid Authorization token. |
403 | Forbidden | The caller lacks permission on the transaction group, the group is not shared with the caller, or CFM is not enabled for the environment. |
404 | Not Found | No transaction exists for the supplied id, or the transactionGroupId does not exist. |
| Field | Type | Description |
|---|---|---|
errors[] | Error | Error entries returned alongside or instead of data. |
Because POST accepts an array, a partial failure is possible in principle — some transactions created, others rejected. No supplied source states whether the operation is atomic per request or per element, or how a partial failure is signalled in errors.
| V2 operation | V3 equivalent | Notes |
|---|---|---|
| Create CFM transactions | POST /api/v3/surveyTransactions | Body schema SurveyTransactionsCreateRequestDTO. data is returned as an array. |
| Fetch CFM transaction | GET /api/v3/surveyTransactions?id= | Single transaction only. No bulk fetch. |
| Delete CFM transaction | DELETE /api/v3/surveyTransactions?id= | Response shape unsettled. |
The structural change is the same one applied across the V3 programme: one resource path, three HTTP methods, replacing three separately-named V2 endpoints. Routing, retry, and observability code that keys on the path must now key on the method as well.
| Value | Meaning |
|---|---|
EMAIL | Survey invitation distributed by email. |
| Value | Meaning |
|---|---|
API | Transactions are pushed programmatically from an external system. This is the type required for the Create Transactions API. |
UDC | Transactions are ingested by the Unified Data Connector (SFTP, Amazon S3, GCS, Azure Blob). |
Import | Transactions are loaded by one-time Excel or CSV file import. |
Source: Help Center — "Workflows accept three types of transaction groups: Unified Data Connector (UDC), API, and Import." The exact string tokens the API returns in transactionGroupType are not declared in sprinklr-v3.yaml (unconstrained type: string) and do not appear in any response sample.
Post-purchase feedback from an e-commerce platform. On order confirmation,
POSTa transaction carryingorderId,purchaseAmount, andpurchaseCategoryinto an API-type transaction group. A Transaction Record Event workflow subscribed to that group fires and triggers a personalized survey distribution on the channel indistributionChannel.Refund and service-recovery surveys. Push a transaction whenever a refund is processed, tagged with the refund reason in
customProperties. A workflow decision node branches on the reason and routes high-value refunds to a longer service-recovery survey.Post-support-interaction surveys. After a support ticket closes, create a transaction carrying ticket status, interaction date, and issue type. Per the Help Center, this lets surveys be "dynamically tailored based on the nature of the support interaction, such as a technical issue or an account query."
Multiple surveys for the same customer across separate events. A customer shops at two locations on different days. Create one transaction per visit. Because each transaction is stored independently rather than overwriting the profile, both events survive and each can drive its own targeted survey — the outcome that is impossible with profile fields alone.
Loyalty programme engagement. Create a transaction on each loyalty redemption. A workflow filters on the redemption tier in
customPropertiesand sends a survey focused on the specific benefits the member received.Service-visit follow-up for field operations. After a technician closes a visit, push a transaction with the visit type and location so the follow-up survey question set matches the work performed.
Pre-flight validation of an ingestion pipeline. After a batch
POST, callGET ?id=for a sample of returned IDs and assert thatuserId,distributionChannel, andcustomPropertiesmatch what was sent. This is the documented purpose of the fetch endpoint — "validate and review transaction attributes."Correcting a mis-ingested record. A transaction created with a wrong
userIdor an incorrect channel would otherwise trigger a survey to the wrong recipient.DELETEit by ID and re-create it correctly. There is no update operation on/surveyTransactions— correction is delete-and-recreate.Data-subject erasure requests. When a customer requests deletion of their interaction history, enumerate their transactions via the Search by Entity API and
DELETEeach by ID. Confirm with the API owner whether this is a hard or soft delete before relying on it for a compliance workflow.