SDK Integration
The SDK routes provide client-side access to AudienceGPT's classification and topic management capabilities. These endpoints use publishable keys (pk_live_ / pk_test_) instead of secret API keys, making them safe to expose in browser JavaScript. All SDK routes include CORS headers for cross-origin requests and follow the same request/response patterns as their dashboard counterparts.
Overview
SDK routes are designed for:
- Embedding classification widgets in consumer-facing websites
- Building custom taxonomy management UIs
- Client-side applications that need to classify topics without a backend proxy
- Platform integrations that need to read mapping data
Authentication
SDK routes authenticate via the Authorization header with a publishable key:
Authorization: Bearer pk_live_x9Kz3mN9pQ2wXyZ5bC...
| Key Prefix | Environment |
|---|---|
pk_live_ | Production |
pk_test_ | Testing/development |
SDK keys are visible in client-side code. While they are safe to expose (scoped to specific operations), you should still restrict their scopes to only the operations your client application needs.
CORS Headers
All SDK routes include the following CORS headers:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, OPTIONS (or GET, OPTIONS for read endpoints)
Access-Control-Allow-Headers: Content-Type, Authorization
Every SDK route also exports an OPTIONS handler for CORS preflight requests, returning 204 No Content.
POST /api/sdk/classify
Classify a topic through the AI-powered pipeline. Mirrors POST /api/classify with SDK key authentication.
Auth: SDK key with classify scope
Request Body
{
"messages": [
{
"role": "user",
"content": "Classify: organic skincare for sensitive skin"
}
]
}
| Field | Type | Required | Description |
|---|---|---|---|
messages | array | Yes | Anthropic message format (max 50 messages) |
Response (200)
{
"text": "{\"topic_name\":\"Organic Skincare - Sensitive Skin\",\"parent_category\":\"Health & Beauty\",\"taxonomy_type\":\"Health & Wellness\",\"subcategory\":\"Skincare\",\"segment_type\":\"B2C\",\"audience_type\":\"Health-Conscious Consumers\",\"keywords\":[\"organic\",\"skincare\",\"sensitive skin\"],\"segment_desc_liveramp\":\"Health-conscious consumers seeking organic skincare products for sensitive skin\",\"segment_desc_tradedesk\":\"Organic skincare for sensitive skin\",\"internal_description\":\"Audience segment targeting consumers interested in organic skincare products formulated for sensitive skin\"}"
}
JavaScript Example
async function classifyTopic(description) {
const response = await fetch("https://app.audiencegpt.com/api/sdk/classify", {
method: "POST",
headers: {
"Authorization": "Bearer pk_live_your_key_here",
"Content-Type": "application/json",
},
body: JSON.stringify({
messages: [{ role: "user", content: `Classify: ${description}` }],
}),
});
if (!response.ok) {
throw new Error((await response.json()).error);
}
const { text } = await response.json();
return JSON.parse(text);
}
POST /api/sdk/analyze-brief
Upload and analyze a campaign brief document. Mirrors POST /api/analyze-brief with SDK key authentication.
Auth: SDK key with classify scope
Request Body
{
"file": {
"data": "JVBERi0xLjQK...",
"mediaType": "application/pdf",
"filename": "campaign-brief.pdf"
}
}
See Campaign Brief API for full request/response details.
POST /api/sdk/check-duplicate
Check if a topic already exists before saving it.
Auth: SDK key with classify scope
Request Body
{
"topic_name": "Organic Skincare Buyers"
}
Response (200)
{
"isDuplicate": false,
"confidence": 0.42,
"existingTopic": null
}
POST /api/sdk/topics
Save a classified topic to your organization's library.
Auth: SDK key with topics:write scope
Request Body
All classification output fields are required:
{
"topic_name": "Organic Skincare - Sensitive Skin",
"parent_category": "Health & Beauty",
"taxonomy_type": "Health & Wellness",
"subcategory": "Skincare",
"segment_type": "B2C",
"keywords": ["organic", "skincare", "sensitive skin"],
"segment_desc_liveramp": "Health-conscious consumers seeking organic skincare...",
"segment_desc_tradedesk": "Organic skincare for sensitive skin",
"internal_description": "Audience segment targeting..."
}
| Field | Type | Required | Description |
|---|---|---|---|
topic_name | string | Yes | Topic name |
parent_category | string | Yes | Parent category (41 types) |
taxonomy_type | string | Yes | Taxonomy type group (13 groups) |
subcategory | string | Yes | Subcategory |
segment_type | string | Yes | B2B, B2C, B2B2C, B2E, B2G |
keywords | array | Yes | Keyword array |
segment_desc_liveramp | string | Yes | LiveRamp description |
segment_desc_tradedesk | string | Yes | Trade Desk description |
internal_description | string | Yes | Internal description |
Response (201)
{
"id": "ot_01hy..."
}
GET /api/sdk/mappings
Bulk export of platform ID mappings for activated topics. This is the primary endpoint for downstream systems that need to resolve AudienceGPT topic IDs to platform-specific segment IDs.
Auth: SDK key with mappings:read scope
Query Parameters
| Parameter | Type | Description |
|---|---|---|
platform | string | Filter by platform (e.g., liveramp, tradedesk) |
connection_id | string | Filter by specific connection |
Response (200)
{
"mappings": [
{
"topic_name": "Tesla Model 3 Buyers",
"org_topic_id": "ot_01hy...",
"legacy_id": null,
"platform": "liveramp",
"platform_segment_id": "lr_seg_12345",
"connection_id": "conn_01...",
"pushed_name": "Auto > EV > Tesla Model 3 Buyers",
"status": "active",
"activated_at": "2026-02-20T10:00:00.000Z"
}
],
"total": 1
}
curl Example
curl "https://app.audiencegpt.com/api/sdk/mappings?platform=liveramp" \
-H "Authorization: Bearer pk_live_your_key_here"
GET /api/sdk/mappings/:topicName
Look up the platform mapping for a specific topic by name.
Auth: SDK key with mappings:read scope
Response (200)
Returns the mapping record for the specified topic name, or 404 if not found.
Client-Side Integration
React Example
import { useState } from "react";
const SDK_KEY = "pk_live_your_key_here";
const API_BASE = "https://app.audiencegpt.com";
function ClassifyWidget() {
const [input, setInput] = useState("");
const [result, setResult] = useState(null);
const [loading, setLoading] = useState(false);
async function handleClassify() {
setLoading(true);
try {
const response = await fetch(`${API_BASE}/api/sdk/classify`, {
method: "POST",
headers: {
Authorization: `Bearer ${SDK_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
messages: [{ role: "user", content: `Classify: ${input}` }],
}),
});
const { text } = await response.json();
setResult(JSON.parse(text));
} finally {
setLoading(false);
}
}
return (
<div>
<input
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="Enter topic to classify..."
/>
<button onClick={handleClassify} disabled={loading}>
{loading ? "Classifying..." : "Classify"}
</button>
{result && (
<pre>{JSON.stringify(result, null, 2)}</pre>
)}
</div>
);
}
Vanilla JavaScript Example
<script>
const SDK_KEY = "pk_live_your_key_here";
async function classify(topicDescription) {
const res = await fetch("https://app.audiencegpt.com/api/sdk/classify", {
method: "POST",
headers: {
"Authorization": `Bearer ${SDK_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
messages: [{ role: "user", content: `Classify: ${topicDescription}` }],
}),
});
const { text } = await res.json();
return JSON.parse(text);
}
// Usage
classify("luxury travel to Maldives").then(result => {
console.log("Category:", result.parent_category);
console.log("Segment:", result.segment_type);
});
</script>
SDK Key Management
SDK keys are created and managed through the dashboard API (requires Clerk session):
| Endpoint | Method | Description |
|---|---|---|
/api/sdk-keys | POST | Create a new SDK key |
/api/sdk-keys | GET | List active SDK keys |
/api/sdk-keys | DELETE | Revoke an SDK key |
See Authentication for full SDK key CRUD documentation.
Error Responses
All SDK endpoints return errors with CORS headers:
{
"error": "Invalid or expired SDK key"
}
| Status | Description |
|---|---|
| 400 | Invalid request body or missing required fields |
| 401 | Invalid, expired, or revoked SDK key, or insufficient scopes |
| 429 | Monthly quota exceeded |
| 500 | Server error |
Next Steps
- Authentication -- Create and manage SDK keys
- Classify API -- Server-side classification reference
- Campaign Brief API -- Document analysis details
- Error Codes -- Complete error reference