Use the AI Feedback API to send customer feedback into Amplitude for AI-powered analysis.
This API uses basic authentication, using the API key and secret key for your project. Pass base64-encoded credentials in the request header like {api-key}:{secret-key}. api-key replaces username, and secret-key replaces the password.
Your authorization header should look something like this:
--header 'Authorization: Basic YWhhbWwsdG9uQGFwaWdlZS5jb206bClwYXNzdzByZAo'
For more information, see Find your API Credentials
| Region | Endpoint |
|---|---|
| Standard server | https://amplitude.com/api/1/ai-feedback |
| EU residency server | https://eu.amplitude.com/api/1/ai-feedback |
Content-Type: application/json.unique_id within a source. Sending the same data twice is safe. Amplitude updates (upserts) existing records.unique_id and include the new parts. Amplitude updates existing parts (matched by their unique_id) in place and adds new parts.To find the source_id for a webhook source, navigate to the source details page in AI Feedback and click the three-dot menu and then click Settings. The page displays the source ID and example request.
For EU data residency, use https://eu.amplitude.com as the base URL instead of https://amplitude.com. For example:
POST https://eu.amplitude.com/api/1/ai-feedback/ingest.Sends customer feedback items into Amplitude. Each item can optionally 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"
}
]
}'
POST /api/1/ai-feedback/ingest HTTP/1.1
Host: amplitude.com
Authorization: Basic {api-key}:{secret-key} #credentials must be base64 encoded
Content-Type: application/json
| Name | Description |
|---|---|
source_id |
Required. String (1–128 characters). The source ID for your feedback source. Find this on the source details page by clicking the three-dot menu and then clicking Settings. |
items |
Required. Array (1–100 items). Feedback items to ingest. |
| Name | Description |
|---|---|
unique_id |
Required. String (max 1024 characters). A stable, unique identifier for this item in your system. Use to deduplicate items. Sending the same unique_id again updates the existing item. |
body |
Optional. String (max 20,000 characters). The feedback text. You can omit body when adding conversation parts to an item that Amplitude already ingested. This lets you 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. This maps directly to the user_id field in Analytics, allowing you to link feedback to user behavior and see 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. |
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. |
{
"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"
}
]
}
Send standalone pieces of feedback (NPS responses, survey answers, 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"
}
]
}'
POST /api/1/ai-feedback/ingest HTTP/1.1
Host: amplitude.com
Authorization: Basic {api-key}:{secret-key} #credentials must be base64 encoded
Content-Type: application/json
{
"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"
}
]
}
Send a support ticket where there is an initial message followed by conversation parts. To add new replies to an existing ticket after the initial import, go 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"
}
]
}
]
}'
POST /api/1/ai-feedback/ingest HTTP/1.1
Host: amplitude.com
Authorization: Basic {api-key}:{secret-key} #credentials must be base64 encoded
Content-Type: application/json
{
"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"
}
]
}
]
}
Send a call transcript where each speaker turn is a conversation part. The item represents the entire call. Each conversation part should represent a new speaker turn and alternate between speakers so the transcript reads as a natural conversation. For call transcripts, you don't need to include a body on the item itself, just send 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"
}
]
}
]
}'
POST /api/1/ai-feedback/ingest HTTP/1.1
Host: amplitude.com
Authorization: Basic {api-key}:{secret-key} #credentials must be base64 encoded
Content-Type: application/json
{
"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"
}
]
}
]
}
To append new conversation parts to an item you have already sent, re-send the item with the same unique_id and include only the new parts. You don't need to include a body or re-send the original item details. Only send 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"
}
]
}
]
}'
POST /api/1/ai-feedback/ingest HTTP/1.1
Host: amplitude.com
Authorization: Basic {api-key}:{secret-key} #credentials must be base64 encoded
Content-Type: application/json
{
"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"
}
]
}
]
}
unique_id.| 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. |
March 24th, 2024
Need help? Contact Support
Visit Amplitude.com
Have a look at the Amplitude Blog
Learn more at Amplitude Academy
© 2026 Amplitude, Inc. All rights reserved. Amplitude is a registered trademark of Amplitude, Inc.