Quickstart
Three steps from zero to a live AI agent.
- 1Pick a vertical persona.
POST /v1/admin/marketplace/applywithvertical_keyto load a sales-ready persona, knowledge base, and tool config — or skip this and use the post-signup wizard at /onboard. - 2Issue an API key. Open Dashboard → Settings → API Keys and click Generate API key. The plaintext key is shown once — store it safely.
- 3Start chatting. Pick a transport: bare HTTP (curl), the JS SDK, the Python SDK, or the drop-in React widget — all four are below.
curl
curl https://api.partython.com/api/v1/respond \
-H "Authorization: Bearer pk_live_..." \
-H "Content-Type: application/json" \
-d '{
"channel": "web",
"channel_user_id": "user-abc",
"message_text": "I need party supplies for 12 kids"
}'JavaScript / TypeScript
import { Brain } from '@partython/brain';
const brain = new Brain({ apiKey: process.env.PARTYTHON_API_KEY });
const result = await brain.respond({
channel: 'web',
channel_user_id: 'user-abc',
message_text: 'I need party supplies for 12 kids',
});
console.log(result.response);Python
from partython_brain import Brain
import os
brain = Brain(api_key=os.environ["PARTYTHON_API_KEY"])
result = brain.respond(
channel="web",
channel_user_id="user-abc",
message_text="I need party supplies for 12 kids",
)
print(result["response"])Issuing API keys
Every API key is tied to a single tenant and a set of allowed scopes. Keys are minted from the dashboard — never from the browser — so the plaintext is generated server-side and shown exactly once.
Generate a key in three clicks
- Open Dashboard → Settings → API Keys.
- Type a label that tells you where the key will live — Production backend, Local dev, Webflow site. The label is for your reference only.
- Click Generate API key. The plaintext appears in a copy-to-clipboard banner; store it before you close the page. After that we only keep the SHA-256 hash.
Keys look like this — click the pill to copy the sample format:
Lost a key? Revoke it from the same screen and issue a fresh one. Old keys remain in the table as revoked so audit trails stay intact.
Plaintext shown once, then discarded. Only the SHA-256 hash is persisted.
Default scope is `respond`. Revoke a single key without touching the others.
Last-used timestamp + lifetime call count surface in the dashboard.
Operators with super-admin access can also issue keys programmatically via POST /v1/admin/api-keys/issue — gated by the brain admin token and intended for internal tooling only. Browser-side code should always go through the dashboard.
Authentication
Every request requires a Bearer token in the Authorization header. Keys are tied to a tenant and scoped to a set of allowed endpoints. Never expose a pk_live_ key in client-side code — front it with your own backend, or use the React widget (it runs against a short-lived public token derived from your key).
Authorization: Bearer pk_live_a1b2c3d4_0123456789abcdef0123456789abcdef0123456789abcdefThe 8-character prefix after pk_live_ is indexed for fast lookup. The remaining 48 hex characters are the secret — leak that, rotate immediately.
POST /api/v1/respond
The single endpoint that powers a conversational turn. Routes through the persona, runs RAG retrieval, dispatches tools, applies guardrails, and returns the assistant's reply.
Request
POST /api/v1/respond HTTP/1.1
Host: api.partython.com
Authorization: Bearer pk_live_...
Content-Type: application/json
{
"channel": "web",
"channel_user_id": "user-abc",
"message_text": "I need party supplies for 12 kids"
}Body fields
| param | type | required | description |
|---|---|---|---|
| channel | string | yes | web · whatsapp · instagram · messenger · sms · email · api |
| channel_user_id | string | yes | Stable id for the conversation participant |
| message_text | string | yes | The customer's message |
| metadata | object | no | Pass-through metadata; surfaces in webhooks + logs |
| dedup_key | string | no | Idempotency key (e.g. Meta event id) — repeats short-circuit |
| has_image | boolean | no | Hint for the smart router |
Response (200)
{
"ok": true,
"request_id": "req_01HV...",
"response": "Got it — for 12 kids, the Mystical Unicorn Bundle covers it. Want me to lock it in?",
"assistant_name": "Astra",
"metadata": {
"tools_called": ["commerce.recommend_products"],
"latency_ms": 842,
"tokens_in": 412,
"tokens_out": 88
}
}Errors
Errors return JSON with an error code and the matching HTTP status. Every response — success or failure — carries an X-Request-Id header.
| status | error | meaning |
|---|---|---|
| 400 | bad_request | Malformed body or missing required field |
| 401 | unauthorized | Missing or malformed Bearer token |
| 403 | forbidden | Key revoked or scope insufficient |
| 404 | not_found | Tenant misconfigured |
| 429 | rate_limited | Per-key per-minute limit hit; retry after Retry-After header |
| 5xx | server_error | Upstream brain failure; safe to retry with exp backoff |
Error response shape
{
"ok": false,
"error": "rate_limited",
"message": "Per-key limit of 60 rpm reached.",
"request_id": "req_01HV..."
}request_id in every support ticket. It lets us pull the full server-side trace — tool calls, prompt, tokens, downstream latency — in one query.Rate limits
Limits are per API key, per minute, and scale with your plan: Starter 60 rpm, Pro 600 rpm, Enterprise 6,000 rpm. Every response includes:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1714915800When you hit the limit, the response is a 429 with a Retry-Afterheader (in seconds). The official SDKs back off automatically; if you're calling the API directly, honour Retry-After before retrying.
Versioning
The version lives in the URL — /api/v1/…. Breaking changes ship as a new prefix (/api/v2/…) and the old version stays live for a minimum of 12 months. Within a version we only add — new fields, new response keys, new channels — never remove or rename. SDK majors track the API major: @partython/brain 1.x targets v1.
SDKs
Maintained by the Partython team. All SDKs share the same error hierarchy, exponential backoff, and request_id surfacing. Click any install command below to copy it.
React widget
One line, anywhere in your app. Renders a floating launcher, persists conversation in localStorage, supports light/dark themes, and works in SSR builds.
import { ChatWidget } from '@partython/brain-react';
export default function App() {
return <ChatWidget apiKey="pk_live_..." theme="light" position="bottom-right" />;
}Webhooks (inbound)
Configure your channel provider to POST events to https://api.partython.com/v1/webhook/{channel}/{tenant_id}. The brain handles signature verification, idempotency, and dispatch to your persona — you just respond from the dashboard or your own backend.
| channel | provider | where to set |
|---|---|---|
| Meta Cloud API | Set under WhatsApp → Configuration | |
| Meta Graph API | Set under Instagram Basic + Webhooks | |
| messenger | Meta Graph API | Set under Messenger → Webhooks |
| Amazon SES (inbound) | SES receipt rule → webhook URL |
Webhook ingress is gated by a deployment flag (BRAIN_WEBHOOK_ENABLED) and is enabled per environment. If your channel webhook returns 404, the ingress router is not mounted yet — contact support to have it turned on for your workspace.
Need a hand?
Stuck on integration? We'll pair with you. Contact support — typical reply within a business day.