# sasuAI API — integration brief for coding agents

This is a plain-text brief meant to be read by an AI coding agent (Claude, Cursor,
Copilot, or similar) integrating a customer's application with the sasuAI API.
A human-readable version of the same contract lives at https://chat.sasusync.com/docs.

## Prerequisites

- Base URL: `https://chat.sasusync.com/v1`
- Auth: header `Authorization: Bearer sk-sasu-...`
- Get a key: create an account at https://chat.sasusync.com/register, then open
  **sasuAI API** in the dashboard sidebar and create a key. It is shown once —
  store it immediately, it cannot be recovered later, only revoked.
- Language target for the reference client below: `curl`
  (pass `?lang=` with `curl`, `python`, `node`, `php`, `java`, `go`, or `react` to switch it)

## Rules

1. Put the key in an environment variable (`SASUAI_API_KEY`). Never hardcode it
   or commit it — it is a live credential billed per token.
2. Always send `Content-Type: application/json` on POST requests.
3. `model` is always `"sasuai-core"`. It's the only value this API
   accepts or returns; omit the field and it defaults to the same thing.
4. `messages` is a non-empty array, role one of `system` / `user` / `assistant`,
   `content` a string. Max 40 messages, max 24,000 characters
   combined across the conversation. This API is stateless — resend the full
   conversation each call.
5. Set `"stream": true` for server-sent events instead of one JSON body. Read
   the wire format below before implementing a parser by hand.
6. Retry only on `429` and `502` — both are transient. `400` and `401` mean fix
   the request or the key; retrying them changes nothing.
7. A `402 insufficient_quota` means the account's credit balance is at zero.
   Surface that to the user with a link to top up — do not silently drop the
   request or retry it.

## Billing model

Prepaid credit, metered per token, no subscription. Money is tracked in
integer units of GHS (100 units = 1.00 GHS).

| Model | Input / 1M tokens | Output / 1M tokens |
|---|---|---|
| `sasuai-core` | 20 units | 60 units |

New accounts start with 0.50 GHS of free credit
automatically — enough to build and test against the real API before paying
anything. Every response carries a `usage` block with the exact token counts
the call was billed on.

## Reference client
```bash
curl https://chat.sasusync.com/v1/chat/completions \
  -H "Authorization: Bearer $SASUAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "sasuai-core",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'
```

This client covers the whole contract: one endpoint, one header, plain JSON.
Nothing else is required to make a first successful call.

## Endpoints

### POST /v1/chat/completions

Request body:

```json
{
  "model": "sasuai-core",
  "messages": [{"role": "user", "content": "..."}],
  "stream": false
}
```

Non-streaming response:

```json
{
  "id": "chatcmpl-...",
  "object": "chat.completion",
  "created": 1757000000,
  "model": "sasuai-core",
  "choices": [
    {"index": 0, "message": {"role": "assistant", "content": "..."}, "finish_reason": "stop"}
  ],
  "usage": {"prompt_tokens": 14, "completion_tokens": 9, "total_tokens": 23}
}
```

Streaming (`"stream": true`) sends server-sent events, one JSON chunk per
`data:` line, terminated by a literal `data: [DONE]`:

```
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","model":"sasuai-core","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","model":"sasuai-core","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]
```

A disconnect mid-stream is billed only for what was actually generated up to
that point, not the full reply.

### GET /v1/models

Returns the models available to your key, with live pricing:

```json
{
  "object": "list",
  "data": [
    {
      "id": "sasuai-core",
      "object": "model",
      "owned_by": "sasuAI",
      "pricing": {"input_per_million_tokens": 20, "output_per_million_tokens": 60, "currency": "GHS"}
    }
  ]
}
```

## Rate limits

| Endpoint | Limit |
|---|---|
| `POST /v1/chat/completions` | 120 requests/minute, 5,000/day |
| `GET /v1/models` | 60 requests/minute |

## Errors

Every failure returns `{"error": {"message", "type", "code"}}` with a matching
HTTP status:

| Status | Type | Meaning |
|---|---|---|
| 400 | `invalid_request_error` | Malformed body — check `messages`. |
| 401 | `authentication_error` | Key missing, mistyped, or revoked. |
| 402 | `insufficient_quota` | Credit balance is zero. Top up to resume. |
| 429 | `rate_limit_error` | Too many requests — back off and retry. |
| 502 | `server_error` | The model failed to complete the request. Safe to retry. |

## Integration checklist

- [ ] API key read from an environment variable, not hardcoded
- [ ] `Content-Type: application/json` set on every POST
- [ ] `model` omitted or set to `"sasuai-core"`
- [ ] Retries limited to `429` and `502`, with backoff
- [ ] `402` is surfaced to the user as "add credit", not retried
- [ ] Long conversations trimmed client-side to stay under
      24,000 characters / 40 messages
- [ ] `usage.total_tokens` read back if the app needs to track spend

Full human-readable docs: https://chat.sasusync.com/docs