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:
FieldDescription
rfm_recency_daysDays since the last transaction (Recency).
rfm_frequencyTotal number of transactions/orders (Frequency).
rfm_monetaryTotal monetary value (Monetary).
churn_scoreChurn probability between 0 and 1.
churn_risklow · medium · high bucket.
abc_categoryValue-based ABC class: A · B · C.
uplift_scoreEstimated incremental impact a campaign would have on this customer.
segment_labelLabel 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 k selection (knee/elbow + silhouette).
  • Churn predictionchurn_score and 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:
  1. Ingestion — raw data is received, validated, and mapped to a schema.
  2. Segmentation — customers are split into segments via RFM + K-Means.
  3. Predictive — churn / uplift scores are computed (optional).
  4. 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:
ChannelRequired fields
custom_webhookurl
sendgridapiKey
mailchimpapiKey, listId
amazon_sesaccessKeyId, secretAccessKey, region
twilioaccountSid, authToken
messagebirdapiKey
slackwebhookUrl
teamswebhookUrl
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.
FreeStarterProEnterprise
Monthly$0$29$99$200
Annual (per month)$0$24$79$189
Rows500K10M100MUnlimited
Customer profiles5,00050,000500,000Unlimited
Model runs550500Unlimited
GenAI ops550500Unlimited
Automations21050Unlimited
Storage0.5 GB5 GB50 GB500 GB
Team seats1525Unlimited

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:
MetricHow it is measured
rowsSum of rowCount across files with status completed.
storageGbSum of uploaded files' sizeBytes ÷ 1024³.
automationsNumber of active automations.
teamSeatsNumber of organization members.
profilesSum of total_customers per project from the Engine.
modelRuns / genaiOpsCounters in the organization's currentUsage.
GET /api/organizations/:orgId/usagejson
{
  "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/billingSession
View billing details (name, tax id, address).
PUT/api/organizations/:orgId/billingSession
Update billing address and tax id; synced to the Stripe customer.
GET/api/organizations/:orgId/invoicesSession
Stripe invoice history (with PDF links).
GET/api/organizations/:orgId/payment-methodsSession
Saved cards (brand, last 4, default).
POST/api/organizations/:orgId/billing-portalSession
Opens a self-serve Stripe Billing Portal session.
POST/api/organizations/:orgId/subscribe-freeSession
Activates the free plan (no Stripe checkout).
POST/api/organizations/:orgId/cancel-subscriptionSession
Cancels at period end (cancel_at_period_end).
POST/api/organizations/:orgId/sync-subscriptionSession
Manual sync with Stripe.
Billing Portal sessionbash
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/contact
Public; no authentication required.
Contact formbash
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:
SurfaceBaseAuthentication
Ingest API (M2M)/api/v1API 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 enabled keys are accepted.
  • An expired (expiresAt) key returns 401.
  • Keys are project-scoped; a mismatched project returns 403.
Creating a key (from the dashboard, session-authenticated):
POST/api/projects/:projectId/api-keysSession
Body: { name, expiresAt? }
Create a keybash
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" }'
Response — 201json
{
  "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 key
Body: 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"
  }'
Response — 202json
{
  "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/progressSession
Live progress (percent + message).
Poll progressbash
curl https://api.segmento.app/api/engine/jobs/8f1c2d3e-.../progress \
  -H "Cookie: <better-auth session>"
Responsejson
{
  "job_id": "8f1c2d3e-...",
  "status": "processing",
  "pct": 64,
  "message": "Segmenting customers"
}
GET/api/engine/jobs/:jobId/statusSession
Persisted status record (result, error_message, timestamps).
GET/api/engine/jobs/:jobId/progress/streamSession
Real-time stream via SSE (no polling).
SSE streambash
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/segmentsSession
Segment list (with metadata).
POST/api/engine/projects/:projectId/segments/previewSession
Preview rule results before committing.
POST/api/engine/projects/:projectId/segmentsSession
Create a custom segment.
PATCH/api/engine/segments/:segmentIdSession
Update a segment (name, rules).
DELETE/api/engine/segments/:segmentIdSession
GET/api/engine/projects/:projectId/customersSession
Paginated customer list (filters + sorting).
GET/api/engine/customers/:customerId/similarSession
Similar customers (embedding-based).
GET/api/engine/projects/:projectId/overviewSession
Aggregate ML statistics.
Example — fetching the customer list with filters:
GET customersbash
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>"
Response — 200json
{
  "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:
filters grammarjson
[
  { "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.
CodeMeaning
400Validation error
401Unauthorized / invalid / expired key
403Forbidden / project mismatch
404Not found
409Conflict (e.g. already subscribed)
422Failed integration test
429Quota or rate limit exceeded
500Server error
503DB / cache / Engine unavailable
Example errorjson
{ "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.
429 responsehttp
HTTP/1.1 429 Too Many Requests
RateLimit-Limit: 1000
RateLimit-Remaining: 0
RateLimit-Reset: 540
Distinguish 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.