---
name: intent-model
description: >
  Call the Warrant intent model (zeroproof-ecommerce-1b): classify the
  payment intent of an assistant conversation into a structured JSON verdict
  over seven intent types. Use this whenever an agent needs to determine what
  a user is trying to buy, pay, send, swap, subscribe to, dispute, or whether
  there is any actionable payment intent at all, via the hosted MCP tool or
  the OpenAI-compatible API.
---

# Calling the Warrant intent model

`zeroproof-ecommerce-1b` reads a payment-assistant conversation and returns
one JSON object describing the user's actionable intent. It distinguishes
seven intent types:

- `spend`: buy/order/book goods or services from a merchant
- `send`: transfer/pay back/tip/donate to a person, wallet, or recipient
- `exchange`: swap/convert/buy/sell an asset or currency
- `recur`: subscription, membership, renewal, auto-pay, or recurring payment
- `bill`: pay a specific bill, invoice, statement, dues, or amount owed
- `reverse`: refund, return, chargeback, dispute, or undoing a prior payment
- `none`: no actionable payment intent

Every verdict has the same shape:

```json
{
  "intent_detected": true,
  "core_type": "spend",
  "details": { "product_name": "...", "total_amount": 129.0, "currency": "USD", "...": null },
  "confidence": 0.9,
  "reason": "One short sentence.",
  "source_message_seqs": [0, 4]
}
```

`details` is shaped per intent type, with explicit `null` for unknown fields.
The model detects intent even when details are incomplete; missing fields
alone never make a conversation `none`.

The model is open weights. The weights and the evaluation set are published
on Hugging Face under the `zero-proof-ai` organization. The hosted endpoint
below serves the same weights with sub-second warm latency.

## Authentication

Both routes require a bearer API key:

```
Authorization: Bearer <API_KEY>
```

Requests without a valid key receive `401 Unauthorized`. Keys are issued by
Warrant; use the key you were provided. To request one, email
[jacob@zeroproofai.com](mailto:jacob@zeroproofai.com) with a sentence about
your use case.

## Option 1: MCP tool (recommended for agents)

The endpoint speaks MCP over streamable HTTP. The server applies the model's
trained prompt format for you; pass only the raw conversation.

- URL: `https://zeroproofai--zeroproof-intent-vllm-mcp.modal.run/mcp`
- Tool: `detect_payment_intent`
- Argument: `messages` — the conversation history, oldest first, each item
  `{"role": "user" | "assistant", "content": "...", "seq": 0}` (`seq` optional)
- Returns: the JSON verdict described above

Register it with an MCP client, for example Claude Code:

```bash
claude mcp add --transport http zeroproof-intent \
  https://zeroproofai--zeroproof-intent-vllm-mcp.modal.run/mcp \
  --header "Authorization: Bearer $API_KEY"
```

## Option 2: OpenAI-compatible API

The model is served behind the standard Chat Completions API:

- Base URL: `https://zeroproofai--zeroproof-intent-vllm-serve.modal.run/v1`
- Model name: `zeroproof-intent`
- Always use `temperature: 0` and `max_tokens: 512`

```python
from openai import OpenAI

client = OpenAI(
    base_url="https://zeroproofai--zeroproof-intent-vllm-serve.modal.run/v1",
    api_key=API_KEY,
)
resp = client.chat.completions.create(
    model="zeroproof-intent",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": user_prompt(conversation)},
    ],
    max_tokens=512,
    temperature=0,
)
verdict = json.loads(resp.choices[0].message.content)
```

On this route you must reproduce the model's trained prompt format exactly;
it is not a general chat model. The system prompt, the per-intent `details`
schemas, and the user-message format are published with the model on the
Hugging Face model card (`zero-proof-ai` organization). The user message
renders the conversation one line per message as
`[seq=N][role] content`, oldest first, preceded by the detail schemas, and
ends with `Return the complete JSON object for this conversation.`

If you cannot reproduce that format faithfully, use the MCP route, which
does it for you.

## Behavior worth knowing

- User messages are ground truth for intent; assistant messages are context
  for offers, prices, and confirmations. The latest amended values win.
- A clear direction toward an action counts as that intent even if the user
  never says an explicit "yes, do it".
- `none` is reserved for genuine non-intent: browsing, questions, status
  checks, chit-chat.
- `source_message_seqs` lists only the user messages that support the final
  verdict, not every user message.
- The response is always a single JSON object with no markdown fencing. At
  `temperature: 0` with the correct prompt format, output parses as JSON;
  treat a parse failure as a signal that your prompt format is wrong.
