Intake-Triage
by carsonlabs
README.md
# Intake Triage & Classification API
A pay-per-call API that accepts raw unstructured text (emails, support tickets, Slack messages, voicemail transcripts) and returns a guaranteed-schema JSON triage object with intent, urgency, sentiment, entities, and routing.
## Quick Start
```bash
curl -X POST https://your-domain.com/triage \
-H "Content-Type: application/json" \
-H "X-API-Key: sk_live_abc123" \
-d '{
"text": "Hi, I placed an order three days ago (order #8821) and still haven't received a shipping confirmation. This is really frustrating. Can someone help? - James, james@example.com",
"context": "ecommerce_support"
}'
```
Response:
```json
{
"schema_version": "v1",
"intent": "order_status_inquiry",
"urgency": "medium",
"sentiment": "frustrated",
"entities": {
"order_id": "8821",
"issue": "missing shipping confirmation",
"contact_name": "James",
"contact_email": "james@example.com",
"product": null,
"company": null,
"phone": null,
"date_mentioned": null
},
"suggested_routing": "order_fulfillment",
"summary": "Customer James reporting no shipping confirmation received 3 days after placing order #8821.",
"tags": ["order", "shipping", "delay"],
"confidence": 0.96,
"processing_time_ms": 312,
"model_used": "gpt-4o-mini"
}
```
## Setup
```bash
git clone <repo-url> && cd intake-triage-api
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # fill in your keys
python main.py
```
## API Endpoints
| Method | Path | Auth | Description |
|--------|------|------|-------------|
| POST | `/triage` | API Key | Classify text and return triage JSON |
| GET | `/health` | None | Health check |
| GET | `/schema` | None | Full JSON Schema of the output model |
| GET | `/usage` | API Key | Current usage stats for your key |
| POST | `/keys/provision` | Admin Key | Create a new API key |
| GET | `/docs` | None | Swagger UI |
## Input Schema
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `text` | string | Yes | Raw unstructured text to classify |
| `context` | string | No | Business context hint (e.g. `ecommerce_support`) |
| `schema_version` | string | No | `"v1"` (default) |
## Output Schema
| Field | Type | Description |
|-------|------|-------------|
| `schema_version` | `"v1"` | Response schema version |
| `intent` | enum | `support_request`, `sales_inquiry`, `billing_question`, `complaint`, `feature_request`, `general_question`, `spam`, `appointment_request`, `refund_request`, `order_status_inquiry`, `technical_issue`, `unclear` |
| `urgency` | enum | `critical`, `high`, `medium`, `low` |
| `sentiment` | enum | `positive`, `neutral`, `frustrated`, `angry`, `confused`, `urgent` |
| `entities` | object | Extracted entities: `order_id`, `issue`, `contact_name`, `contact_email`, `product`, `company`, `phone`, `date_mentioned` (all nullable) |
| `suggested_routing` | enum | `support_team`, `sales_team`, `billing_team`, `technical_team`, `management`, `order_fulfillment`, `unroutable` |
| `summary` | string | One-sentence summary |
| `tags` | string[] | Lowercase keyword tags |
| `confidence` | float | 0.0–1.0 confidence score |
| `processing_time_ms` | int | Processing time in ms |
| `model_used` | string | LLM model used |
## Authentication
Pass your API key in the `X-API-Key` header with every request.
To get an API key, email **api@yourdomain.com** with your use case.
## Rate Limits
60 requests per minute per API key. Exceeding this returns `429`.
## Using as an MCP Server (Claude Desktop)
Add to your Claude Desktop `claude_desktop_config.json`:
```json
{
"mcpServers": {
"intake-triage": {
"url": "http://localhost:8001/sse"
}
}
}
```
The MCP server exposes one tool: `triage_text(text, context?)` which returns the full triage JSON object.
## Using in n8n
1. Add an **HTTP Request** node
2. Set method to **POST**
3. URL: `https://your-domain.com/triage`
4. Headers: `X-API-Key: your_key`, `Content-Type: application/json`
5. Body (JSON): `{ "text": "{{ $json.message }}" }`
6. The response JSON is directly usable in downstream nodes for routing
## Using in Make / Zapier
Use the HTTP module with the same POST configuration as above. The guaranteed JSON schema means you can map output fields directly without parsing.
## Pricing
| Plan | Price | Calls/month |
|------|-------|-------------|
| Free | $0 | 500 |
| Starter | $19/mo | 10,000 |
| Agency | $99/mo | 100,000 |
## Marketplace Listings
- **RapidAPI**: https://rapidapi.com/your-listing (coming soon)
- **Smithery**: https://smithery.ai/your-listing (coming soon)
## Deployment
### Docker
```bash
docker build -t intake-triage-api .
docker run -p 8000:8000 -p 8001:8001 --env-file .env intake-triage-api
```
### Fly.io
```bash
fly launch
fly secrets set OPENAI_API_KEY=sk-... ADMIN_KEY=...
fly deploy
```
## Running Tests
```bash
pytest tests/ -v
```
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues