Documentation
Learn productization, billing, support, and the API — all on one page.
Product
Segmento is a customer-intelligence platform that turns transactional data into actionable customer segments. It combines RFM analysis, AI-based clustering, churn prediction, and multi-channel automation in a single flow — no data scientist required.
Overview
Segmento is multi-tenant. Every resource lives inside the hierarchy below, which the API and the dashboard share.
- Organization — the tenant and billing entity. Plan, quotas, and team members are defined here.
- Project — a dataset and its segmentation world. API keys are project-scoped.
- Files / Customers — raw data uploaded or sent via the API, and the customer profiles derived from it.
- Segments — customer groups defined by clustering or by rules.
- Automations / Actions — multi-channel actions triggered against segments.
Core Concepts
The core customer fields you will see in API responses and in the dashboard:
| Field | Description |
|---|---|
rfm_recency_days | Days since the last transaction (Recency). |
rfm_frequency | Total number of transactions/orders (Frequency). |
rfm_monetary | Total monetary value (Monetary). |
churn_score | Churn probability between 0 and 1. |
churn_risk | low · medium · high bucket. |
abc_category | Value-based ABC class: A · B · C. |
uplift_score | Estimated incremental impact a campaign would have on this customer. |
segment_label | Label of the segment the customer is assigned to. |
ML Capabilities
The Engine (ML layer) produces the following analyses per project:
- RFM analysis — recency / frequency / monetary and return rate per customer.
- K-Means segmentation — clustering with automatic
kselection (knee/elbow + silhouette). - Churn prediction —
churn_scoreand a risk bucket. - Uplift modeling — targeting that maximizes campaign impact.
- Similar customers — nearest customers over pgvector embeddings.
- Hybrid rule filtering — segments that blend clustering with manual rules.
- ABC analysis — value-based customer classification.
Project Lifecycle
Every project runs through the same pipeline:
- Ingestion — raw data is received, validated, and mapped to a schema.
- Segmentation — customers are split into segments via RFM + K-Means.
- Predictive — churn / uplift scores are computed (optional).
- Action — campaigns/automations bound to segments are triggered (optional).
Data enters two ways: CSV/XLSX upload from the dashboard, or API ingest (
POST /api/v1/ingest). Both feed the same processing queue.Integrations
Actions (campaigns/automations) are delivered over the channels below. Credentials required per channel:
| Channel | Required fields |
|---|---|
custom_webhook | url |
sendgrid | apiKey |
mailchimp | apiKey, listId |
amazon_ses | accessKeyId, secretAccessKey, region |
twilio | accountSid, authToken |
messagebird | apiKey |
slack | webhookUrl |
teams | webhookUrl |
Secret fields (
apiKey, authToken, secretAccessKey) are masked as [REDACTED] on read and are never returned.Billing
Plans & Quotas
Start free, scale when you are ready. All quotas are per organization.
| Free | Starter | Pro | Enterprise | |
|---|---|---|---|---|
| Monthly | $0 | $29 | $99 | $200 |
| Annual (per month) | $0 | $24 | $79 | $189 |
| Rows | 500K | 10M | 100M | Unlimited |
| Customer profiles | 5,000 | 50,000 | 500,000 | Unlimited |
| Model runs | 5 | 50 | 500 | Unlimited |
| GenAI ops | 5 | 50 | 500 | Unlimited |
| Automations | 2 | 10 | 50 | Unlimited |
| Storage | 0.5 GB | 5 GB | 50 GB | 500 GB |
| Team seats | 1 | 5 | 25 | Unlimited |
To confirm
Enterprise pricing is shown to match the landing page ($200/mo · $189/yr); however, the billing source (
plan-limits.ts) defines Enterprise as null (“contact us”). This conflict should be resolved before publishing.Usage Metering
Each metric is computed as follows:
| Metric | How it is measured |
|---|---|
rows | Sum of rowCount across files with status completed. |
storageGb | Sum of uploaded files' sizeBytes ÷ 1024³. |
automations | Number of active automations. |
teamSeats | Number of organization members. |
profiles | Sum of total_customers per project from the Engine. |
modelRuns / genaiOps | Counters in the organization's currentUsage. |
{
"plan": "free",
"data": {
"rows": { "used": 250000, "limit": 500000 },
"profiles": { "used": 3200, "limit": 5000 },
"automations": { "used": 1, "limit": 2 },
"modelRuns": { "used": 3, "limit": 5 },
"genaiOps": { "used": 0, "limit": 5 },
"storageGb": { "used": 0.25, "limit": 0.5 },
"teamSeats": { "used": 1, "limit": 1 }
}
}When storage and model-run limits are exceeded, the request is rejected with
429.Managing Your Subscription
Billing runs on Stripe. The relevant endpoints (owner/admin role required):
GET
/api/organizations/:orgId/billingSessionView billing details (name, tax id, address).
PUT
/api/organizations/:orgId/billingSessionUpdate billing address and tax id; synced to the Stripe customer.
GET
/api/organizations/:orgId/invoicesSessionStripe invoice history (with PDF links).
GET
/api/organizations/:orgId/payment-methodsSessionSaved cards (brand, last 4, default).
POST
/api/organizations/:orgId/billing-portalSessionOpens a self-serve Stripe Billing Portal session.
POST
/api/organizations/:orgId/subscribe-freeSessionActivates the free plan (no Stripe checkout).
POST
/api/organizations/:orgId/cancel-subscriptionSessionCancels at period end (cancel_at_period_end).
POST
/api/organizations/:orgId/sync-subscriptionSessionManual sync with Stripe.
curl -X POST https://api.segmento.app/api/organizations/org_01HXX.../billing-portal \
-H "Cookie: <better-auth session>"Trials & Cancellation
Paid plans are offered with a trial period. Cancellation happens at period end — the subscription stays active until the end of the billing period; it is not cut off immediately.
To confirm
The trial length (14 days in marketing copy) comes from Stripe price configuration, not hardcoded in the codebase. A refund policy is not defined in code; both should be confirmed with the product team before publishing.
Support
Contact Channels
For now, email is the only support channel. The contact form in the dashboard, or the
POST /api/contact endpoint directly, delivers your message to [email protected].POST
/api/contactPublic; no authentication required.
curl -X POST https://api.segmento.app/api/contact \
-H "Content-Type: application/json" \
-d '{
"name": "Ada Lovelace",
"email": "[email protected]",
"message": "Segmentation job 8f1c2d3e... failed at 40% with a schema error."
}'Required fields:
name (min 2), email (valid email), message (min 10 characters).Filing a Good Request
To speed up your request, include where possible:
- Organization name / slug
- Project ID
- The relevant
job_id(for a failed or slow segmentation) - The relevant API endpoint and a timestamp
- The full error message /
error_message
Scope & Response Times
Support is currently provided asynchronously over email; there is no live ticketing/portal yet.
To confirm
SLAs, support hours, and response-time commitments are not defined in code; to be confirmed with the product team.
API Reference
Introduction & Base URLs
All requests are JSON-based. Base URL:
https://api.segmento.app/api (local development: http://localhost:3001/api). The API consists of two distinct surfaces:| Surface | Base | Authentication |
|---|---|---|
| Ingest API (M2M) | /api/v1 | API key (sk_live_) |
| Dashboard / Session API | /api/engine/* | Session cookie |
Today, only data ingestion (
/api/v1/ingest) is protected by an API key. Segment/customer read endpoints require a session (via the dashboard, the /api/engine/* proxy).Authentication
Machine-to-machine (M2M) requests are authorized with an API key. The key format is
sk_live_<64 hex> and is sent as the header Authorization: Bearer sk_live_....- Keys are stored as SHA-256 and compared timing-safe.
- Only
enabledkeys are accepted. - An expired (
expiresAt) key returns401. - Keys are project-scoped; a mismatched project returns
403.
Creating a key (from the dashboard, session-authenticated):
POST
/api/projects/:projectId/api-keysSessionBody:
{ name, expiresAt? }curl -X POST https://api.segmento.app/api/projects/proj_01HXX.../api-keys \
-H "Cookie: <better-auth session>" \
-H "Content-Type: application/json" \
-d '{ "name": "Production ingest", "expiresAt": "2027-01-01T00:00:00Z" }'{
"id": "f0e9c8b7-...-uuid",
"name": "Production ingest",
"keyPrefix": "sk_live_a1b2c3",
"key": "sk_live_a1b2c3d4e5f6...the-only-time-this-is-returned",
"enabled": true,
"expiresAt": "2027-01-01T00:00:00Z",
"createdAt": "2026-06-07T10:00:00Z"
}The raw key (
key) is returned only once, at creation. Save it immediately; it is never shown again.Data Ingestion
POST
/api/v1/ingestAPI keyBody:
project_id (required), records (1–10,000 objects), and an optional batch_id. Records are converted to CSV and queued; the response is 202 Accepted with a job_id.curl -X POST https://api.segmento.app/api/v1/ingest \
-H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"project_id": "proj_01HXX...",
"records": [
{ "customer_id": "C-1001", "order_date": "2026-05-01", "amount": 129.90, "country": "TR" },
{ "customer_id": "C-1002", "order_date": "2026-05-02", "amount": 59.00, "country": "DE" }
],
"batch_id": "may-2026-orders"
}'{
"job_id": "8f1c2d3e-4a5b-6c7d-8e9f-0a1b2c3d4e5f",
"file_id": "8f1c2d3e-4a5b-6c7d-8e9f-0a1b2c3d4e5f",
"status": "processing"
}Error cases:
401 (missing/invalid/expired key), 403 (project mismatch), 400 (empty or more than 10,000 records), 500 (server error).Async Jobs
Ingest and segmentation are asynchronous (Celery + Redis). Track progress with the returned
job_id.GET
/api/engine/jobs/:jobId/progressSessionLive progress (percent + message).
curl https://api.segmento.app/api/engine/jobs/8f1c2d3e-.../progress \
-H "Cookie: <better-auth session>"{
"job_id": "8f1c2d3e-...",
"status": "processing",
"pct": 64,
"message": "Segmenting customers"
}GET
/api/engine/jobs/:jobId/statusSessionPersisted status record (result, error_message, timestamps).
GET
/api/engine/jobs/:jobId/progress/streamSessionReal-time stream via SSE (no polling).
curl -N https://api.segmento.app/api/engine/jobs/8f1c2d3e-.../progress/stream \
-H "Cookie: <better-auth session>"Terminal states:
completed | failed. Progress records expire in Redis after ~1 hour; for older jobs, fall back to /status.Resource Endpoints
The endpoints below live under
/api/engine/* and use the session cookie.GET
/api/engine/projects/:projectId/segmentsSessionSegment list (with metadata).
POST
/api/engine/projects/:projectId/segments/previewSessionPreview rule results before committing.
POST
/api/engine/projects/:projectId/segmentsSessionCreate a custom segment.
PATCH
/api/engine/segments/:segmentIdSessionUpdate a segment (name, rules).
DELETE
/api/engine/segments/:segmentIdSessionGET
/api/engine/projects/:projectId/customersSessionPaginated customer list (filters + sorting).
GET
/api/engine/customers/:customerId/similarSessionSimilar customers (embedding-based).
GET
/api/engine/projects/:projectId/overviewSessionAggregate ML statistics.
Example — fetching the customer list with filters:
curl "https://api.segmento.app/api/engine/projects/proj_01HXX.../customers\
?limit=2&churn_risk=high&sort_by=rfm_monetary&sort_dir=desc" \
-H "Cookie: <better-auth session>"{
"customers": [
{
"id": "c0a8f1e2-...-uuid",
"customer_id_hash": "CUST_8F2A",
"segment_label": "Champions",
"churn_score": 0.82,
"churn_risk": "high",
"abc_category": "A",
"rfm_recency_days": 12,
"rfm_frequency": 9,
"rfm_monetary": 4210.5,
"return_rate": 0.04,
"uplift_score": 0.13,
"last_transaction_at": "2026-05-28T10:14:00Z",
"extra_features": { "country": "TR" }
}
],
"total": 5234,
"page": 1,
"pages": 2617
}For advanced filtering, pass JSON conditions to the
filters query parameter:[
{ "field": "rfm_monetary", "op": "range", "min": 1000, "max": 50000 },
{ "field": "churn_risk", "op": "in", "values": ["low", "medium"] }
]Error Handling
Gateway errors are
{ "error": "..." }; Engine errors are { "detail": "..." }. Messages are localized based on the Accept-Language header.| Code | Meaning |
|---|---|
400 | Validation error |
401 | Unauthorized / invalid / expired key |
403 | Forbidden / project mismatch |
404 | Not found |
409 | Conflict (e.g. already subscribed) |
422 | Failed integration test |
429 | Quota or rate limit exceeded |
500 | Server error |
503 | DB / cache / Engine unavailable |
{ "error": "Forbidden: API key does not belong to this project" }Rate Limits
Global limit: 1000 requests per 15 minutes. The
Authorization header is used as the key — so each API key has its own bucket. Standard RateLimit-* headers are returned in responses.HTTP/1.1 429 Too Many Requests
RateLimit-Limit: 1000
RateLimit-Remaining: 0
RateLimit-Reset: 540Distinguish the two sources of
429: the transport rate limit in this section versus the quota overage in Billing. Exponential backoff is recommended for 429 on the client.