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?