# Source Agnostic API V3 — Developer Guide

- **Applies to:** Sprinklr Source Agnostic API V3 (`/api/v3/deflect`)
- **V2 API reference:** [Source Agnostic | Sprinklr Developer Portal](https://dev.sprinklr.com/source-agnostic-message)


## 1. Overview

The Source Agnostic APIs allow you to import third‑party messages into Sprinklr, update their status, and delete conversations.
They provide a unified way to manage external messages and cases within Sprinklr.

**Source Agnostic V3 exposes operations on a single resource path — `/api/v3/sourceAgnostic` — differentiated by HTTP method:**

| **Operation** | **Method** | **Path** |
|  --- | --- | --- |
| Send Message | POST | `/api/v3/sourceAgnostic` |
| Update Message Status | PATCH | `/api/v3/sourceAgnostic` |
| Delete Conversation | DELETE | `/api/v3/sourceAgnostic` |


## 2. Base URLs and environments

All API calls are sent to the production endpoint:

```
https://api3.sprinklr.com/{env}/api/v3
```

So the Source Agnostic resource in production is:

```
https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic
```

Replace `{env}` with your assigned environment identifier (`prod0`, `prod2`, etc.).

## 3. Authentication and common headers

All Source Agnostic API calls are authenticated with OAuth 2.0.

| **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 | All requests |
| Accept | application/json | Declares the acceptable response type | All requests |


## 4. Write Operations

### 4.1 Send a Source Agnostic Message

**`POST /api/v3/sourceAgnostic?accountId={id}`**

Imports a third‑party message into Sprinklr. A case and profile are created automatically.

#### Query Parameter

| **Parameter** | **Required/Optional** | **Description** | **Type** |
|  --- | --- | --- | --- |
| accountId | Required | Unique identifier for the Source Agnostic account. | Integer |


#### Steps to Extract Account ID from Sprinklr UI

1. Navigate to **All Settings**.
2. Open the **Accounts** page.
3. Locate the account you want.
4. Click the **three‑dot icon** next to the account name.
5. Select **Details** from the dropdown. A third‑pane window opens.
6. In the window, click the **copy URL icon** at the top right.
7. Paste the copied URL into any encoder/decoder tool.
8. The account ID will appear in the decoded URL.


**Example:**
If the decoded URL contains `/ACCOUNT/100426226/OVERVIEW`, then the account ID is **100426226**.

#### Request Parameters

| **Parameter** | **Required/Optional** | **Description** | **Type** |
|  --- | --- | --- | --- |
| messageId | Required | Unique identifier for the message. Must be unique for every request. | String |
| conversationId | Required | Unique identifier for the conversation. Use the same ID for multiple messages in one conversation. A new ID creates a new case. | String |
| senderProfile | Required | Profile details of the sender. See senderProfile table below. | Object |
| receiverProfile | Required | Profile details of the receiver. See receiverProfile table below. | Object |
| content | Required | Content of the message. | Object |
| content.text | Optional | Text of the message. | String |
| content.isRichText | Optional | Required when sending HTML content. Set to `true` if content is HTML. | Boolean |
| content.attachment | Optional | Required for messages with attachments. Object containing attachment details. See the attachment object table below. | Object |
| messageProperties | Optional | Custom properties at the message level. | Object |
| conversationProperties | Optional | Custom properties at the case level. | Object |


#### SenderProfile / ReceiverProfile Object

| **Parameter** | **Required/Optional** | **Description** | **Type** |
|  --- | --- | --- | --- |
| id | Required | Unique identifier for the sender or receiver profile. | Integer |
| screenName | Optional | Screen name or handle of the sender/receiver. | String |
| name | Optional | Full name of the sender/receiver. Recommended for easier identification in Sprinklr. | String |
| firstName | Optional | First name of the sender/receiver. | String |
| lastName | Optional | Last name of the sender/receiver. | String |
| email | Optional | Email address of the sender/receiver. | String |
| phoneNo | Optional | Phone number of the sender/receiver. | String |
| profileURL | Optional | Profile URL of the sender/receiver. | String |
| profileImageURL | Optional | Profile image URL of the sender/receiver. | String |
| properties | Optional | Custom properties for the sender/receiver. | Object |


#### Attachment Object

| **Parameter** | **Required/Optional** | **Description** | **Type** |
|  --- | --- | --- | --- |
| type | Required | Type of attachment. **Supported values:** `IMAGE`, `VIDEO`, `DOC`, `AUDIO`, `BASE64`. | String |
| url | Required (except Base64) | URL of the attachment. Must be a valid Sprinklr CDN URL obtained via the Media Upload API. | String |
| base64EncodedContent | Required (Base64 only) | Base64‑encoded content for the attachment. | String |
| fileName | Required (Base64 only) | File name of the attachment when using Base64. | String |
| title | Optional | Title of the attachment. | String |
| description | Optional | Description of the attachment. | String |
| previewUrl / previewImageUrl | Optional | Preview URL or image preview for the attachment. | String |
| mimeType | Optional | MIME type of the attachment (e.g., `image/jpeg`, `video/mp4`, `application/pdf`, `audio/mpeg`). | String |


#### Example Request — Text Message

```bash
curl --location --request POST 'https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic?accountId=66122694' \
--header 'Authorization: Bearer {token}' \
--header 'Content-Type: application/json' \
--data '{
  "messageId": "br_test_text_1",
  "conversationId": "shamyak_test_1_1004",
  "senderProfile": { "id": "918410614581" },
  "receiverProfile": { "id": "19283994232" },
  "content": { "text": "This is a text message" }
}'
```

#### Example — Send Image Attachment

```bash
curl --location --request POST 'https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic?accountId=66122694' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
  "messageId": "br_test_image_1",
  "conversationId": "shamyak_test_1_1004",
  "senderProfile": { "id": "918410614581" },
  "receiverProfile": { "id": "19283994232" },
  "content": {
    "text": "This is a test message with image",
    "attachment": {
      "type": "IMAGE",
      "url": "https://cdn.sprinklr.com/qa6/media/123456789.png",
      "title": "Test_image1.png",
      "description": "This is a test image",
      "mimeType": "image/jpeg"
    }
  }
}'
```

#### Example — Send Video Attachment

```bash
curl --location --request POST 'https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic?accountId=66122694' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
  "messageId": "br_test_video_1",
  "conversationId": "br_test_conversation_video",
  "senderProfile": { "id": "918410614581" },
  "receiverProfile": { "id": "19283994232" },
  "content": {
    "text": "This is a test message with video",
    "attachment": {
      "type": "VIDEO",
      "url": "https://cdn.sprinklr.com/qa6/media/test_video.mp4",
      "title": "Test_video.mp4",
      "description": "Sample video attachment",
      "mimeType": "video/mp4"
    }
  }
}'
```

#### Example — Send Document Attachment

```bash
curl --location --request POST 'https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic?accountId=66122694' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
  "messageId": "br_test_doc_1",
  "conversationId": "br_test_conversation_doc",
  "senderProfile": { "id": "918410614581" },
  "receiverProfile": { "id": "19283994232" },
  "content": {
    "text": "This is a test message with document",
    "attachment": {
      "type": "DOC",
      "url": "https://cdn.sprinklr.com/qa6/media/test_doc.pdf",
      "title": "Contract.pdf",
      "description": "Signed contract document",
      "mimeType": "application/pdf"
    }
  }
}'
```

#### Example — Send Audio Attachment

```bash
curl --location --request POST 'https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic?accountId=66122694' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
  "messageId": "br_test_audio_1",
  "conversationId": "br_test_conversation_audio",
  "senderProfile": { "id": "918410614581" },
  "receiverProfile": { "id": "19283994232" },
  "content": {
    "text": "This is a test message with audio",
    "attachment": {
      "type": "AUDIO",
      "url": "https://cdn.sprinklr.com/qa6/media/test_audio.mp3",
      "title": "Voice Note"
    }
  }
}'
```

#### Example — Send BASE64 Attachment

```bash
curl --location --request POST 'https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic?accountId=66122694' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
  "messageId": "br_test_base64_1",
  "conversationId": "br_test_conversation_base64",
  "senderProfile": { "id": "918410614581" },
  "receiverProfile": { "id": "19283994232" },
  "content": {
    "text": "This is a test message with base64 image",
    "attachment": {
      "type": "BASE64",
      "base64EncodedContent": "<base64-string>",
      "fileName": "Test_image.jpg",
      "title": "Base64 Image",
      "description": "Converted image attachment"
    }
  }
}'
```

#### Example — Send Multimedia Attachment

```bash
curl --location --request POST 'https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic?accountId=66122694' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
  "messageId": "br_test_multi_1",
  "conversationId": "br_test_conversation_multi",
  "senderProfile": { "id": "918410614581" },
  "receiverProfile": { "id": "19283994232" },
  "content": {
    "text": "Testing multiple attachments",
    "attachment": {
      "type": "MULTI_MEDIA",
      "attachments": [
        {
          "type": "DOC",
          "url": "https://cdn.sprinklr.com/qa6/media/test_doc1.pdf",
          "title": "Test Doc 1",
          "mimeType": "application/pdf"
        },
        {
          "type": "DOC",
          "url": "https://cdn.sprinklr.com/qa6/media/test_doc2.pdf",
          "title": "Test Doc 2",
          "mimeType": "application/pdf"
        }
      ]
    }
  }
}'
```

#### Example — Enrich Case and Message Custom Properties

```bash
curl --location --request POST 'https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic?accountId=66122694' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
  "messageId": "br_test_properties_1",
  "conversationId": "br_test_conversation_properties",
  "senderProfile": { "id": "19283994233" },
  "receiverProfile": { "id": "91841061431" },
  "content": { "text": "Test message" },
  "messageProperties": {
    "_c_63fdcfded4572f6e1021beff": [ "Test1" ]
  },
  "conversationProperties": {
    "_c_63fdcfded4572f6e1021beff": [ "Test2" ]
  }
}'
```

#### Example — Send HTML Content

```bash
curl --location --request POST 'https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic?accountId=66122694' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
  "messageId": "br_test_html_2",
  "conversationId": "shamyak_test_1_1004",
  "senderProfile": { "id": "19283994233" },
  "receiverProfile": { "id": "91841061431" },
  "content": {
    "text": "<div style=\\\"border:1px solid #ccc; padding:10px;\\\">\\n<p style=\\\"text-align:center;\\\"><b>Need assistance?</b> Fill out our <a href=\\\"https://forms.office.com/r/5wTBFPQ7DC\\\">feedback form</a>.</p>\\n</div>",
    "isRichText": true
  }
}'
```

### 4.2 Update Message Status

**`PATCH /api/v3/sourceAgnostic?accountId={id}&conversationId={id}&messageId={id}&status={value}`**

Updates the status of a message already imported into Sprinklr.

#### Query Parameters

| **Parameter** | **Required / Optional** | **Description** | **Type** |
|  --- | --- | --- | --- |
| accountId | Required | Unique identifier for the Source Agnostic account. You can get the account ID from the Sprinklr UI (see steps below). | String |
| conversationId | Required | Unique identifier that the brand generates each time a new conversation (composed of several messages) is created within Sprinklr. When sending messages within the same conversation, the `conversationId` should remain the same. Passing a new ID will create a new case. | String |
| messageId | Required | Unique identifier of the message whose status you want to update. **Dev Notes:** `messageId = sourceType + "_" + sourceId + "_" + ChannelCreatedTime + "_" + ChannelType + "_" + MessageType + "_" + channelMessageId` | String |
| status | Required | New status to assign to the message. **Valid values:** `sent`, `delivered`, `read`, `failed`. **Dev Notes:** Status updates apply only to existing brand messages and are limited to a single message per request. | String |
| errorMessage | Optional | Brief description explaining the reason for message failure. | String |


#### Steps to Extract Message ID from Sprinklr UI

To find the message ID in the Sprinklr UI:

1. In **Care Console**, open the relevant case.
2. Double‑click the message whose status you want to update.
3. Click on **Properties**.
4. In the **ID** field, the message ID is the value following the prefix `PID_`.


**Example:**
If the ID field shows `PID_123456789`, then the message ID is **123456789**.

#### Example Request

```bash
curl --location --request PATCH 'https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic?accountId=66122694&conversationId=shamyak_test_1_1004&messageId=shamyak_test_1_104&status=read' \
--header 'Authorization: Bearer {token}' \
--header 'Content-Type: application/json'
```

## 5. Delete Operations

### 5.1 Delete a Conversation

**`DELETE /api/v3/sourceAgnostic?conversationId={id}`**

Deletes a conversation and all associated messages and case data. This action is irreversible.

#### Query Parameter

| **Parameter** | **Required/Optional** | **Description** | **Type** |
|  --- | --- | --- | --- |
| conversationId | Required | Unique identifier of the conversation to be deleted. Deleting a conversation removes all associated messages and case data. | String |


#### Example Request

```bash
curl --location --request DELETE 'https://api3.sprinklr.com/{env}/api/v3/sourceAgnostic?conversationId=br_test_conversation_video' \
--header 'Authorization: Bearer {Access Token}' \
--header 'Content-Type: application/json'
```

## 6. Response format and status codes

All Source Agnostic API responses return a consistent envelope:

```json
{
  "data": Object | String | Boolean,
  "errors": []
}
```

### Envelope Fields

| **Field** | **Type** | **Description** |
|  --- | --- | --- |
| data | Object / String / Boolean | Response payload. Examples: case ID (string), `true` for status update success, or object details. |
| errors | Array | List of error messages (empty if none). |


### Example — Send Message Response

```json
{
  "data": "120119884",
  "errors": []
}
```

### Example — Update Status Response

```json
{
  "data": true,
  "errors": []
}
```

### Example — Delete Conversation Response

```json
200 OK
```

### 6.2 Response codes

| HTTP Code | Scenario | Description |
|  --- | --- | --- |
| `200 OK` | Success | Profiles found and returned successfully |
| `400 Bad Request` | Invalid Parameters | Missing required parameters or invalid parameter combinations |
| `401 Unauthorized` | Authentication Failed | Invalid or missing `Authorization` token |
| `403 Forbidden` | Insufficient Permissions | User lacks `VIEW` permission for `AUDIENCE_PROFILE` |
| `404 Not Found` | No Profiles Found | No profiles match the search criteria |
| `500 Internal Server Error` | Server Error | Unexpected server-side error occurred |


## 7. Migration from V2 to V3

The Source Agnostic APIs have been redesigned in **V3** for consistency, clarity, and improved lifecycle control.
Below is a comparison of **V2 vs V3 endpoints and behavior**:

| **Operation** | **V2 Endpoint** | **V3 Endpoint** | **Key Differences** |
|  --- | --- | --- | --- |
| Send Message | `POST /api/v2/source-agnostic/{accountId}/send` | `POST /api/v3/sourceAgnostic?accountId={id}` | V2 used path parameter for accountId; V3 uses query parameter. |
| Update Status | `POST /api/v2/source-agnostic/{accountId}/updateStatus` | `PATCH /api/v3/sourceAgnostic?accountId={id}&conversationId={id}&messageId={id}&status={value}` | V2 used POST with accountId in path; V3 uses PATCH with query parameters for granular control. |
| Close Conversation | `POST /api/v2/source-agnostic/closeConversation?conversationId={conversationId}` | `DELETE /api/v3/sourceAgnostic?conversationId={id}` | V2 used POST; V3 uses DELETE for proper REST semantics. |