Topics API
The Topics API provides full CRUD operations for managing classified audience topics in your organization's library. Topics are the core data objects in AudienceGPT -- each represents a classified audience segment with taxonomy placement, DSP naming, and intent signals. The API supports listing with pagination and filtering, single-topic operations, bulk reclassification, history audit trails, and aggregate statistics.
List Topics
Retrieve a paginated, filtered, sorted list of topics in your organization's library.
GET /api/topics
Auth: API key with topics:read scope, or Clerk session
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number |
pageSize | number | 25 | Items per page (max 100) |
sortBy | string | created_at | Sort column: topic_name, parent_category, segment_type, taxonomy_type, audience_type, created_at |
sortOrder | string | desc | asc or desc |
search | string | -- | Free-text search across topic names |
taxonomyType | string | -- | Filter by taxonomy type group (13 groups) |
parentCategory | string | -- | Filter by parent category (41 types) |
subcategory | string | -- | Filter by subcategory (L0 tree node) |
subcategoryL1 | string | -- | Filter by subcategory L1 level |
subcategoryL2 | string | -- | Filter by subcategory L2 level |
subcategoryL3 | string | -- | Filter by subcategory L3 level |
subcategoryL4 | string | -- | Filter by subcategory L4 level |
segmentType | string | -- | B2B, B2C, B2B2C, B2E, B2G |
audienceType | string | -- | Filter by audience type (14 types) |
iabCode | string | -- | Filter by IAB content taxonomy code |
engineVersion | string | -- | Filter by engine version (e.g., 2.5) |
source | string | -- | Filter by topic source (e.g., import, sync, matrix, catalog) |
hasExternalId | boolean | -- | Filter by presence of external ID |
internalId | string | -- | Search within external IDs |
sensitivity | string | -- | Filter by sensitivity flag |
intensity | string | -- | Filter by intent intensity level |
buyerJourney | string | -- | Filter by buyer journey stage |
Response (200)
{
"data": [
{
"id": "ot_01hy...",
"topic_name": "Tesla Model 3 Buyers",
"parent_category": "Auto",
"taxonomy_type": "Automotive & Vehicles",
"subcategory": "Electric Vehicles",
"segment_type": "B2C",
"audience_type": "In-Market Buyers",
"iab_code": "IAB2",
"keywords": ["tesla", "model 3", "electric vehicle"],
"segment_name_tradedesk": "Auto > EV > Tesla Model 3 Buyers",
"segment_name_liveramp": "Auto_EV_Tesla_Model_3_Buyers",
"segment_name_internal": "Tesla Model 3 Buyers",
"segment_desc_liveramp": "In-market consumers actively researching Tesla Model 3...",
"segment_desc_tradedesk": "Tesla Model 3 EV buyers",
"internal_description": "Audience segment targeting consumers with purchase intent for Tesla Model 3",
"engine_version": "2.5",
"performance_score": null,
"external_id": null,
"created_at": "2026-02-25T10:00:00.000Z",
"updated_at": "2026-02-25T10:00:00.000Z"
}
],
"total": 1,
"page": 1,
"pageSize": 25,
"totalPages": 1
}
curl Example
curl "https://app.audiencegpt.com/api/topics?page=1&pageSize=10&segmentType=B2C&parentCategory=Auto" \
-H "Authorization: Bearer txadv_your_api_key"
TypeScript Example
async function listTopics(filters: Record<string, string> = {}) {
const params = new URLSearchParams({ page: "1", pageSize: "25", ...filters });
const response = await fetch(
`https://app.audiencegpt.com/api/topics?${params}`,
{
headers: { "Authorization": `Bearer ${API_KEY}` },
}
);
return response.json();
}
// List all B2B technology topics
const topics = await listTopics({
segmentType: "B2B",
taxonomyType: "Technology & Telecom",
});
Create a Topic
Save a new classified topic to your organization's library.
POST /api/topics
Auth: API key with topics:write scope, or Clerk session
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
topic_name | string | Yes | The topic name |
parent_category | string | No | Parent category (41 types) |
taxonomy_type | string | No | Taxonomy type group (13 groups) |
subcategory | string | No | Subcategory |
segment_type | string | No | B2B, B2C, B2B2C, B2E, B2G |
keywords | string[] | No | Related keywords |
segment_desc_liveramp | string | No | LiveRamp segment description |
segment_desc_tradedesk | string | No | Trade Desk segment description |
internal_description | string | No | Internal description |
engine_version | string | No | Defaults to current engine version (2.5) |
_batchId | string | No | Associate with an import batch |
Response (201)
{
"id": "ot_01hy...",
"topic_name": "Tesla Model 3 Buyers",
"parent_category": "Auto",
"taxonomy_type": "Automotive & Vehicles",
"subcategory": "Electric Vehicles",
"segment_type": "B2C",
"engine_version": "2.5",
"created_at": "2026-02-25T10:00:00.000Z"
}
curl Example
curl -X POST https://app.audiencegpt.com/api/topics \
-H "Authorization: Bearer txadv_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"topic_name": "Tesla Model 3 Buyers",
"parent_category": "Auto",
"taxonomy_type": "Automotive & Vehicles",
"subcategory": "Electric Vehicles",
"segment_type": "B2C",
"keywords": ["tesla", "model 3", "ev"],
"internal_description": "Consumers interested in purchasing a Tesla Model 3"
}'
Update a Topic
Update fields on an existing topic in your library.
PATCH /api/topics/:id
Auth: API key with topics:write scope, or Clerk session
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | The topic ID (global topic ID linked to your org) |
Request Body
All fields are optional. Only provided fields are updated.
| Field | Type | Description |
|---|---|---|
topic_name | string | Updated topic name |
parent_category | string | Updated parent category (41 types) |
taxonomy_type | string | Updated taxonomy type group (13 groups) |
subcategory | string | Updated subcategory |
segment_type | string | Updated segment type |
Response (200)
{
"id": "tp_01hy...",
"topic_name": "Tesla Model 3 EV Buyers",
"parent_category": "Auto",
"taxonomy_type": "Automotive & Vehicles",
"subcategory": "Electric Vehicles",
"segment_type": "B2C"
}
Error Responses
| Status | Description |
|---|---|
| 400 | No valid fields to update |
| 404 | Topic not found or not linked to your org |
Delete Topics (Bulk)
Remove topics from your organization's library.
DELETE /api/topics
Auth: API key with topics:write scope, or Clerk session with library:delete permission
Request Body
{
"ids": ["ot_01hy...", "ot_02ab..."]
}
Response (200)
{
"deleted": 2
}
Reclassify a Single Topic
Re-run classification on an existing topic using the current engine version. Supports optional AI-powered mode.
POST /api/topics/:id/reclassify
Auth: API key with topics:write scope, or Clerk session
Request Body (optional)
{
"llm": true
}
| Field | Type | Default | Description |
|---|---|---|---|
llm | boolean | false | When true, uses Claude Sonnet 4.6 with web search. When false, uses rule-based local classification. |
Response (200)
Returns the updated topic record plus reclassification metadata:
{
"id": "ot_01hy...",
"topic_name": "Tesla Model 3 Buyers",
"parent_category": "Auto",
"taxonomy_type": "Automotive & Vehicles",
"engine_version": "2.5",
"llm": true,
"fallback": false
}
| Field | Description |
|---|---|
llm | Whether LLM mode was requested |
fallback | If true, the LLM call failed and local classification was used as fallback |
Error Responses
| Status | Description |
|---|---|
| 404 | Topic not found |
| 429 | LLM quota exceeded (only when llm: true) |
Bulk Reclassify Topics
Reclassify multiple topics in a single request.
POST /api/topics/reclassify
Auth: API key with topics:write scope, or Clerk session
Request Body
{
"ids": ["ot_01hy...", "ot_02ab...", "ot_03cd..."],
"llm": false
}
| Field | Type | Required | Description |
|---|---|---|---|
ids | string[] | Yes | Topic IDs to reclassify |
llm | boolean | No | Use AI-powered reclassification (default: false) |
Limits:
- Rule-based mode: max 500 topics per request
- LLM mode: max 100 topics per request
Response (200)
{
"total": 3,
"success": 3,
"failed": 0,
"errors": [],
"llm": false,
"llmCount": 0,
"fallbackCount": 0
}
LLM reclassification is quota-checked and usage-tracked. Each topic counts as one classification for billing purposes.
Topic History
Retrieve the audit trail for a specific topic, showing all changes over time.
GET /api/topics/:id/history
Auth: API key with topics:read scope, or Clerk session
Response (200)
Returns up to 200 history entries ordered by most recent first:
[
{
"id": "hist_01...",
"orgTopicId": "ot_01hy...",
"changeType": "reclassified",
"changedBy": "user_2xyz...",
"previousValues": {
"engine_version": "2.4",
"parent_category": "Technology",
"segment_type": "B2B"
},
"newValues": {
"engine_version": "2.5",
"parent_category": "Auto",
"segment_type": "B2C"
},
"source": "reclassify:llm",
"metadata": { "llm": true, "fallback": false },
"changedAt": "2026-02-25T12:00:00.000Z"
}
]
Change types: created, imported, synced, reclassified, metadata_enrichment, field_edit, activated, deactivated.
Topic Statistics
Get aggregate statistics for your organization's topic library.
GET /api/topics/stats
Auth: API key with topics:read scope, or Clerk session
Response (200)
{
"total": 1250,
"bySegmentType": {
"B2C": 800,
"B2B": 350,
"B2B2C": 100
},
"byTaxonomyType": {
"Automotive & Vehicles": 150,
"Technology & Telecom": 300,
"Financial Services": 200
}
}
Topic Facets
Get distinct filter values available in your library for building filter UIs.
GET /api/topics/facets
Auth: API key with topics:read scope, or Clerk session
Response (200)
{
"parentCategories": ["Auto", "Business Technology", "Insurance"],
"taxonomyTypes": ["Automotive & Vehicles", "Technology & Telecom"],
"subcategories": ["Electric Vehicles", "Luxury Vehicles"],
"subcategoryL1s": ["Battery Technology", "Charging Infrastructure"],
"subcategoryL2s": [],
"subcategoryL3s": [],
"subcategoryL4s": [],
"audienceTypes": ["In-Market Buyers", "Business Decision Makers"],
"segmentTypes": ["B2B", "B2C", "B2B2C"]
}
Check Duplicate
Check if a topic already exists in your library before saving.
POST /api/topics/check-duplicate
Auth: API key with classify scope, or Clerk session
Request Body
{
"topic_name": "Tesla Model 3 Buyers",
"parent_category": "Auto"
}
Response (200)
{
"isDuplicate": true,
"confidence": 0.97,
"existingTopic": {
"id": "ot_01hy...",
"topic_name": "Tesla Model 3 Buyers"
}
}
Duplicate detection uses 256-dimension hash embeddings with cosine similarity. A similarity score of 0.95+ blocks the duplicate, while 0.75-0.95 generates a warning.
Export Topics
Export your topic library as CSV or JSON with full filtering support.
GET /api/export
Auth: API key with export scope, or Clerk session
Query Parameters
| Parameter | Type | Description |
|---|---|---|
format | string | csv (default) or json |
full | string | true for full export with DSP names and platform outputs (owner only) |
| All filter params | -- | Same filter parameters as GET /api/topics |
Response
CSV format: Streaming CSV with Content-Type: text/csv and Content-Disposition: attachment headers. Standard export includes core fields plus 7-layer breakdown. Full export adds DSP names, descriptions, scores, and platform output columns.
JSON format: Full topic records as a JSON array.
# Export as CSV with filters
curl "https://app.audiencegpt.com/api/export?format=csv&segmentType=B2C" \
-H "Authorization: Bearer txadv_your_api_key" \
-o topics.csv
# Full JSON export
curl "https://app.audiencegpt.com/api/export?format=json&full=true" \
-H "Authorization: Bearer txadv_your_api_key"
Activation Status
Check which topics in your library have active platform activations.
GET /api/topics/activation-status
Auth: API key with topics:read scope, or Clerk session
Returns a mapping of topic IDs to their activation status across platforms.
Next Steps
- Classify API -- Classify new topics before saving
- Import API -- Bulk import topics from CSV files
- Catalog API -- Browse and add topics from the global catalog
- Activations API -- Push topics to DSP platforms