AI Feedback API
Request requirements and limits
- All endpoints use HTTP Basic auth. Use your project's API key as the username and your secret key as the password.
- The request body must be JSON with
Content-Type: application/json. - Maximum payload size is 5 MB.
- Each request accepts 1–100 feedback items.
- Amplitude deduplicates items and conversation parts by their
unique_idwithin a source. Sending the same data twice is safe because Amplitude upserts existing records. - To append new conversation parts to an existing item, re-send the item with the same
unique_idand include the new parts. Amplitude upserts existing parts (matched byunique_id) and adds new parts.
Find your source ID
To find the source_id for a webhook source, go to the source details page in AI Feedback, select the three-dot menu, then select Settings. The page displays the source ID and an example request.
EU data residency
For EU data residency, use https://eu.amplitude.com as the base URL instead of https://amplitude.com. For example:
- Ingest feedback:
POST https://eu.amplitude.com/api/1/ai-feedback/ingest.
Ingest feedback
Sends customer feedback items to Amplitude. Each item can include conversation parts for threaded feedback such as support tickets, call transcripts, or chat conversations.
POST https://amplitude.com/api/1/ai-feedback/ingest
curl -X POST 'https://amplitude.com/api/1/ai-feedback/ingest' \
-u '{api_key}:{secret_key}' \
-H 'Content-Type: application/json' \
-d '{
"source_id": "YOUR_SOURCE_ID",
"items": [
{
"unique_id": "review-789",
"body": "The search feature is broken on mobile",
"author": "Jane Doe",
"user_id": "user-123",
"created_at": "2026-03-15T10:30:00Z"
}
]
}'
Body parameters
| Name | Description |
|---|---|
source_id | Required. String (1–128 characters). The source ID for your feedback source. Find this on the source details page by selecting the three-dot menu, then Settings. |
items | Required. Array (1–100 items). Feedback items to ingest. |
Item object
| Name | Description |
|---|---|
unique_id | Required. String (max 1024 characters). A stable, unique identifier for this item in your system. Used to deduplicate items. Sending the same unique_id again updates the existing item. |
body | Optional. String (max 20,000 characters). The feedback text. Omit body when adding conversation parts to an item Amplitude already ingested, to append new replies without re-sending the original item details. |
author | Optional. String (max 512 characters). Display name of the person who wrote this item. |
email | Optional. String (max 512 characters). Email address of the author. Must be a valid email. |
user_id | Optional. String (max 1024 characters). The Amplitude user ID. Maps directly to the user_id field in Analytics, which links feedback to user behavior and shows feedback alongside behavioral data in cohorts and charts. |
url | Optional. String (max 2048 characters). URL associated with this item, for example a source page or ticket link. Must be a valid URL. |
created_at | Optional. ISO 8601 datetime string. Denotes the creation of the feedback. Defaults to now. |
conversation_parts | Optional. Array (max 100). Follow-up messages or replies belonging to this item. |
Conversation part object
Each conversation part uses the same fields as an item, except body is required (min 1 character) and conversation_parts can't be nested.
| Name | Description |
|---|---|
unique_id | Required. String (max 1024 characters). A stable, unique identifier for this conversation part in your system. Used for deduplication. |
body | Required. String (max 20,000 characters). The text content. |
author | Optional. String (max 512 characters). Display name of the person who wrote this part. |
email | Optional. String (max 512 characters). Email address of the author. |
user_id | Optional. String (max 1024 characters). The Amplitude user ID. This maps directly to the user_id field in Analytics. |
url | Optional. String (max 2048 characters). URL associated with this conversation part. |
created_at | Optional. ISO 8601 datetime string. Denotes the creation of the feedback. Defaults to now. |
Response
{
"ingested": 2,
"failed": 0,
"errors": []
}
| Property | Description |
|---|---|
ingested | Number of items successfully ingested. |
failed | Number of items that failed validation or processing. |
errors | Array of error objects. Each has unique_id (string) and error (string) describing the failure. |
If some items fail:
{
"ingested": 1,
"failed": 1,
"errors": [
{
"unique_id": "ticket-9999",
"error": "Body text exceeds maximum length"
}
]
}
Examples
Simple feedback
Send standalone feedback such as NPS responses, survey answers, or reviews. Each piece of feedback is its own item with no conversation parts.
curl -X POST 'https://amplitude.com/api/1/ai-feedback/ingest' \
-u '{api_key}:{secret_key}' \
-H 'Content-Type: application/json' \
-d '{
"source_id": "YOUR_SOURCE_ID",
"items": [
{
"unique_id": "review-789",
"body": "The search feature is broken on mobile",
"author": "Jane Doe",
"user_id": "user-123",
"created_at": "2026-03-15T10:30:00Z",
"url": "https://feedback.example.com/reviews/789"
},
{
"unique_id": "nps-response-4822",
"body": "The onboarding flow was confusing and I almost gave up.",
"author": "Bob Johnson",
"created_at": "2026-03-20T15:00:00Z"
}
]
}'
Support ticket with replies
Send a support ticket with an initial message followed by conversation parts. To add new replies to an existing ticket after the initial import, refer to Add replies to an existing item.
curl -X POST 'https://amplitude.com/api/1/ai-feedback/ingest' \
-u '{api_key}:{secret_key}' \
-H 'Content-Type: application/json' \
-d '{
"source_id": "YOUR_SOURCE_ID",
"items": [
{
"unique_id": "ticket-456",
"body": "I need to export my dashboard data to Excel but I cannot find the option",
"author": "Jane Doe",
"user_id": "user-123",
"created_at": "2026-03-10T09:00:00Z",
"url": "https://support.example.com/tickets/456",
"conversation_parts": [
{
"unique_id": "ticket-456-1",
"body": "Thanks for reaching out! The export feature is under Settings > Data Export.",
"author": "Support Agent",
"email": "agent@company.com",
"url": "https://support.example.com/tickets/456/1",
"created_at": "2026-03-10T09:15:00Z"
},
{
"unique_id": "ticket-456-2",
"body": "I see it now, but it only exports CSV. We really need native Excel support.",
"author": "Jane Doe",
"user_id": "user-123",
"created_at": "2026-03-10T09:20:00Z"
}
]
}
]
}'
Call transcript
Send a call transcript where each speaker turn is a conversation part. The item represents the entire call. Alternate conversation parts between speakers so the transcript reads as a natural conversation. For call transcripts, omit body on the item itself and send only the individual conversation parts.
curl -X POST 'https://amplitude.com/api/1/ai-feedback/ingest' \
-u '{api_key}:{secret_key}' \
-H 'Content-Type: application/json' \
-d '{
"source_id": "YOUR_SOURCE_ID",
"items": [
{
"unique_id": "call-123",
"author": "Sales Rep",
"created_at": "2026-03-12T14:00:00Z",
"url": "https://gong.io/calls/123",
"conversation_parts": [
{
"unique_id": "call-123-1",
"body": "How does that compare to the competition on pricing?",
"author": "Buyer",
"user_id": "user-456",
"created_at": "2026-03-12T14:00:18Z"
},
{
"unique_id": "call-123-2",
"body": "Great question. Our base tier starts at...",
"author": "Sales Rep",
"created_at": "2026-03-12T14:00:22Z"
}
]
}
]
}'
Add replies to an existing item
To append new conversation parts to an item you already sent, re-send the item with the same unique_id and include only the new parts. Omit body and the original item details. Send only the unique_id and the new conversation parts.
curl -X POST 'https://amplitude.com/api/1/ai-feedback/ingest' \
-u '{api_key}:{secret_key}' \
-H 'Content-Type: application/json' \
-d '{
"source_id": "YOUR_SOURCE_ID",
"items": [
{
"unique_id": "ticket-456",
"conversation_parts": [
{
"unique_id": "ticket-456-3",
"body": "We have added Excel export in the latest release. Can you try again?",
"author": "Support Agent",
"email": "agent@company.com",
"created_at": "2026-03-11T10:00:00Z"
}
]
}
]
}'
Include only the new conversation parts. You don't need to re-send parts Amplitude already ingested. Re-sending them is safe because Amplitude upserts them based on their unique_id.
Status and error codes
| Code | Description |
|---|---|
200 OK | Successful request. |
400 Bad Request | Invalid request body — missing required fields or validation errors. Response includes detailed validation issues. |
401 Unauthorized | Missing authentication. |
403 Forbidden | Invalid credentials, or the source identified by source_id isn't a webhook type. |
404 Not Found | No source found matching the provided source_id. |
Was this helpful?