Developer Documentation
Manage keys →
SentX API
OpenAI-compatible chat completions with vision and document understanding. Streaming. Pay-per-token, top up with Stripe.
Base URL: https://api.sentx.ai/v1
Drop-in: works with any OpenAI SDK (Python, JS, curl) and every OpenAI-compatible client.
1. Get a key
- Sign in to sentx.ai → sidebar → API.
- Click + Create new key, give it a name. Copy it now — the full key is shown exactly once.
- Add credits: + Top Up, pick
$5–$1000, complete Stripe checkout.
Keys start with sk-. Max 25 active keys per account.
2. First call
Python
from openai import OpenAI
client = OpenAI(api_key="sk-YOUR_KEY", base_url="https://api.sentx.ai/v1")
r = client.chat.completions.create(
model="sentx-v1",
messages=[{"role": "user", "content": "What is the capital of France?"}],
)
print(r.choices[0].message.content)
print(r.usage)curl
curl https://api.sentx.ai/v1/chat/completions \
-H "Authorization: Bearer $SENTX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "sentx-v1",
"messages": [{"role": "user", "content": "What is the capital of France?"}]
}'3. Streaming
stream = client.chat.completions.create(
model="sentx-v1",
messages=[{"role": "user", "content": "Explain black holes in 2 paragraphs"}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)The final chunk carries usage (OpenAI-standard). Send request header X-Include-Cost: 1 to also receive usage.cost_cents.
4. System messages
You can influence tone/style with a role="system" message. Safety rules always take precedence.
client.chat.completions.create(
model="sentx-v1",
messages=[
{"role": "system", "content": "Reply in under 200 chars. Be concise."},
{"role": "user", "content": "Thoughts on index funds?"},
],
)Max 2,000 characters.
5. End-user identity
Optional fields to identify the end-user behind a request and to label a conversation. Omit them for simple stateless calls; stock OpenAI clients that don't send them are unaffected.
| Field | Where to send it | What it is |
|---|---|---|
user | request body (OpenAI-standard), or the X-User-Id header | A stable, unique identifier for your end-user. |
user_name | request body via extra_body (top-level for curl), or the X-User-Name header | The end-user's display name. |
X-Session-Id | request header | A stable identifier for the conversation — reuse it across the conversation's requests, use a new value for a new conversation. |
When both a header and its body field are sent, the header wins.
Python
client.chat.completions.create(
model="sentx-v1",
messages=[{"role": "user", "content": "..."}],
user="user-42",
extra_body={"user_name": "Alex"},
)curl
curl https://api.sentx.ai/v1/chat/completions \
-H "Authorization: Bearer $SENTX_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Session-Id: conv-8a1f2c" \
-d '{
"model": "sentx-v1",
"user": "user-42",
"user_name": "Alex",
"messages": [{"role": "user", "content": "Hello"}]
}'JSON body fields (user, user_name) accept UTF-8 directly. The X-* headers are Latin-1 only — percent-encode values with non-Latin-1 characters (Arabic, CJK, emoji, accented names; urllib.parse.quote / encodeURIComponent).
6. Attachments
Three ways to attach an image or document.
A. Inline base64 (images, ≤10 MB)
import base64
with open("chart.png", "rb") as f:
b64 = base64.b64encode(f.read()).decode()
client.chat.completions.create(
model="sentx-v1",
messages=[{"role": "user", "content": [
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}},
{"type": "text", "text": "What does this chart show?"},
]}],
)B. Files API (any size, reusable across turns)
Upload once, reference by file_id:
f = client.files.create(file=open("report.pdf", "rb"), purpose="assistants")
client.chat.completions.create(
model="sentx-v1",
messages=[{"role": "user", "content": [
{"type": "input_file", "file_id": f.id},
{"type": "text", "text": "Summarize this PDF in 3 bullets."},
]}],
)Supported: png, jpeg, webp, gif, mp4, webm, mov, pdf, docx, xlsx, csv, txt, md.
C. Remote URLs — not supported
http(s):// URLs are rejected. Use inline base64 or the Files API.
Per-file cap: 25 MB. Cumulative cap: 500 MB. Retention: 30 days. Max 100 live files.
7. Pricing
| Cents per 1M tokens | USD per 1M tokens | |
|---|---|---|
| Input | 300 | $3.00 |
| Output | 1000 | $10.00 |
- Minimum 1 cent per billable request.
- Maximum $5.00 per single request.
- Round half up.
The response usage block reports exact token counts. With X-Include-Cost: 1 header, also cost_cents.
Credits never expire. No monthly minimum.
8. Rate limits
- 60 requests / minute per API key.
- 5 concurrent streams per API key.
- 5 API-key creations / hour per account.
- 25 active API keys per account.
Exceeding returns 429 rate_limit_exceeded.
9. Errors
All errors:
{"error": {"message": "...", "type": "...", "code": "..."}}| HTTP | code | Meaning |
|---|---|---|
| 401 | invalid_api_key | Key not recognized, revoked, or wrong format. |
| 402 | insufficient_balance | Balance too low. Top up at sentx.ai. |
| 400 | unsupported_url_scheme | http(s):// URL in content. Use data: or Files API. |
| 400 | invalid_file_format | Upload failed format check. |
| 409 | max_keys_reached | Revoke an old key. |
| 422 | av_hit | File failed antivirus scan. |
| 429 | rate_limit_exceeded | Slow down. |
| 500 | internal_error | Retry with exponential backoff. |
Stock OpenAI SDKs surface 402 as APIStatusError/PermissionDeniedError; branch on err.status_code.
10. Files API
POST /v1/files multipart (file, purpose) → {id, bytes, expires_at, ...}
GET /v1/files list your files
GET /v1/files/{id} metadata
DELETE /v1/files/{id} deleteDuplicate bytes (SHA-256 match) deduplicate automatically. The id is a stable reference valid until deletion or retention expiry.
11. Support
- Dashboard: sentx.ai
- Email: [email protected]
Integrator notes
- Model name in requests: use
"sentx-v1". Any model string is accepted; the server ignores it. usage.cost_centsis an optional extension inside the standardusageblock. Set request headerX-Include-Cost: 1to receive it. Standard OpenAI clients ignore the extra field.- SSE framing is standard:
data: {chunk}\n\nevents terminated bydata: [DONE]\n\n. The finalchat.completion.chunkcarriesusage.