Developer Documentation

Manage keys →

SentX API — v3.0

The SentX API gives you programmatic access to SentX 3.0: an assistant that thinks in steps, searches the web on its own, and builds real deliverables — documents, diagrams, charts, and images — as objects you can download, reference, and iterate on across turns.

Base URL:

https://api.sentx.ai/v3
text

Drop-in compatible: works with any OpenAI SDK (Python, JS, curl) and every OpenAI-compatible client. All 3.0 features arrive as additive fields inside standard chat-completion chunks — a plain OpenAI client simply ignores them and still gets clean text.

Migrating from v1? The legacy /v1 endpoint keeps working unchanged for existing integrations. New work should use /v3. Switching is one line: change the base URL and you're done — same keys, same billing, same request shape.


1. Get an API key

  1. Sign in at sentx.aiSettings → Manage API.
  2. Click + Create new key. Copy it now — the full key is shown exactly once.
  3. Keys start with sk-. You can hold up to 25 active keys.
  4. Top up your API balance ($5–$1000) from the same page.

Treat keys like passwords. Revoke a leaked key immediately; revocation is instant.

2. First call

Python:

from openai import OpenAI client = OpenAI( api_key="sk-YOUR_KEY", base_url="https://api.sentx.ai/v3", ) r = client.chat.completions.create( model="sentx-3", messages=[{"role": "user", "content": "Make me a one-page PDF cheat sheet on HTTP status codes."}], ) print(r.choices[0].message.content)
python

JavaScript:

import OpenAI from "openai"; const client = new OpenAI({ apiKey: "sk-YOUR_KEY", baseURL: "https://api.sentx.ai/v3", }); const r = await client.chat.completions.create({ model: "sentx-3", messages: [{ role: "user", content: "Latest news on EU AI regulation — short summary." }], }); console.log(r.choices[0].message.content);
js

curl:

curl https://api.sentx.ai/v3/chat/completions \ -H "Authorization: Bearer $SENTX_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "sentx-3", "messages": [{"role": "user", "content": "Hello!"}]}'
bash

Model name: use sentx-3. Other model strings are accepted for client compatibility.

3. Output modes

By default the assistant has its full toolset: web search plus file generation (documents, diagrams, charts, images). You can narrow that per request.

ModeHowWhat you get
Full (default)Text + web search + generated files (artifact events)
Text + search, no files"modalities": ["text"]Plain text answers; the assistant still searches the web when useful; it will never produce files
Text only, no search"modalities": ["text"] + "extra_body": {"skip_search": true}Plain text, no autonomous web searching (links you paste can still be opened)
Full, no search"extra_body": {"skip_search": true}Generated files allowed, no autonomous web searching
r = client.chat.completions.create( model="sentx-3", messages=[{"role": "user", "content": "Explain OAuth2 in simple terms."}], modalities=["text"], # plain text output — no files )
python

Notes:

  • modalities defaults to ["text", "files"]. Passing ["text"] removes the assistant's ability to build files entirely for that request — nothing is generated and then hidden; the capability itself is off, so answers stay coherent.
  • A modalities list without "text" is rejected with invalid_request_error.
  • Both fields also work inside extra_body for SDKs that don't pass unknown top-level fields.

4. Streaming

Set stream=True for standard server-sent events:

stream = client.chat.completions.create( model="sentx-3", messages=[{"role": "user", "content": "Build a bar chart of the 5 largest economies by GDP."}], stream=True, ) for chunk in stream: if chunk.choices and chunk.choices[0].delta.content: print(chunk.choices[0].delta.content, end="")
python

Wire format: data: {chunk}\n\n frames terminated by data: [DONE]\n\n. The final chunk carries usage; send header X-Include-Cost: 1 to add usage.cost_cents.

Answer text arrives only in delta.content — that never changes. Everything else 3.0 adds is extra keys on delta, described next. On /v3 these events are on by default; send header X-Progress-Stream: 0 if you want a bare OpenAI stream with text and artifacts only.

5. Event reference

Each event is an extra key inside choices[0].delta of a normal chat.completion.chunk. Unknown keys are safe to ignore.

delta.act — activity timeline

The assistant's live activity feed: what it is doing right now (thinking, running a tool, building a file).

{"act": {"id": 3, "op": "start", "kind": "tool", "label": "Searching the web", "chars": {"think": 0, "text": 0, "args": 41}}}
json
  • id — activity id, increases monotonically.
  • opstart | tick (heartbeat/progress) | done | fail.
  • kindmodel (reasoning/writing) or tool (executing an action).
  • label — short human-readable description. Display strings; do not parse or branch on them.
  • chars — live character counters {think, text, args} for progress display.
  • ms — duration, present on done/fail.
  • obj — object id (obj1, el2, …) when the activity produced an object.

delta.step — phase rows

Coarser phase updates for long tool runs: {"sid": 2, "label": "Rendering document", "status": "active" | "done" | "error", "detail": "..."}. A UI can show these as checklist rows.

delta.step_data — expandable step output

Optional payload attached to a step: {"sid": 2, "label": "...", "content": "<text ≤20k chars>", "images": ["<base64>", ...]}. Useful for "show work" panels.

delta.reasoning_chars — thinking meter

A running integer count of the assistant's internal reasoning length for the current activity. It is a count only — reasoning text is never exposed. Use it for a live "thinking…" indicator.

delta.artifact — a generated file

Emitted whenever the assistant finishes building a deliverable. Common fields:

  • typedocument | diagram | chart | image.
  • object_id — stable object handle (obj1, el2, …), see §6.
  • title — display name.
  • file_id — id in the Files API, present on generated types (document, diagram, chart); download the bytes any time within 30 days via GET /v3/files/{file_id}/content (see §7).
  • embed_id — reference id when the artifact is embedded inside a document.

Per type:

  • documentmime_type (application/pdf), file_base64 (the PDF bytes), consumed_object_ids (objects folded into this document).
  • diagramimage_base64 (PNG), source (editable source), theme, aspect.
  • chartimage_base64 (PNG), source (chart spec).
  • image — an image you provided, echoed back as a registered element for UI rendering (image_base64; no file_id — you already have the bytes).

Generated artifacts stream inline as base64 and are stored under your key, so you can drop the base64 and fetch by file_id later.

Two rarer companions: delta.artifact_remove ({"object_id": "el2"} — the object was deleted/superseded) and delta.artifact_rename ({"object_id": "obj1", "new_object_id": "el3"} — the object was reclassified, e.g. a standalone figure became part of a document).

delta.search_sources — web sources

When the assistant searched the web: the list of sources it read (title + URL). Show them as citations.

delta.queue_position — queue status

If the platform is briefly saturated, an integer position while you wait. Usually absent.

Final usage chunk

{"usage": {"prompt_tokens": 812, "completion_tokens": 401, "total_tokens": 1213, "cost_cents": 2}}
json

cost_cents appears when you send X-Include-Cost: 1.

6. Objects & elements

Every deliverable the assistant builds is an object with a stable id:

  • obj1, obj2, … — finals: standalone deliverables (a PDF, a chart, an image).
  • el1, el2, … — elements: building material that lives inside a final (a figure inside a document).

Ids are never reused. If an object is deleted, its id is retired permanently.

Iterating across turns. The API is stateless — you send the conversation each turn. To let the assistant edit objects from earlier turns instead of rebuilding from scratch, echo back an objects map in the request body:

{ "model": "sentx-3", "messages": [...full conversation...], "objects": { "obj1": {"kind": "document", "source": "<the source you received>", "title": "Cheat sheet"} } }
json

Send each object's kind, source, and title exactly as you received them in its artifact event. Objects the assistant deleted should be echoed as {"kind": "tombstone"} so their ids stay retired. If you don't echo objects, the conversation still works — the assistant just rebuilds files instead of editing them.

7. Files API

Same endpoints handle your uploads (inputs) and the assistant's generated files (outputs):

POST /v3/files multipart (file, purpose) → {id, bytes, expires_at, ...} GET /v3/files list your files GET /v3/files/{id} metadata GET /v3/files/{id}/content raw bytes (download) DELETE /v3/files/{id} delete
text

Uploads as input. Upload once, then reference in a message:

f = client.files.create(file=open("report.pdf", "rb"), purpose="assistants") r = client.chat.completions.create( model="sentx-3", messages=[{"role": "user", "content": [ {"type": "text", "text": "Summarize this."}, {"type": "input_file", "file_id": f.id}, ]}], )
python

Small images can also go inline as base64 image_url parts (≤10 MB). Remote http(s):// URLs are not supported and are rejected.

Supported input formats: png, jpeg, webp, gif, mp4, webm, mov, pdf, docx, xlsx, csv, txt, md. Limits: 25 MB per file, 500 MB cumulative, 100 live files, 30-day retention.

Generated files as output. Every artifact with a file_id is fetchable:

curl -H "Authorization: Bearer $SENTX_API_KEY" \ https://api.sentx.ai/v3/files/FILE_ID/content -o result.pdf
bash

Generated files follow the same 30-day retention.

8. Non-streaming

Without stream, you get one final JSON response. choices[0].message.content holds the answer text; generated files appear in a top-level artifacts array on the response — same objects as the streaming artifact events, with file_id set and the inline base64 omitted (fetch the bytes via the Files API; base64 is included only in the rare case storage failed).

9. System messages, identity, sessions

  • System messages are allowed (max 2,000 characters). Safety rules always take precedence.
  • End-user identity: pass user (body) or X-User-Id (header) with your own stable id per end user — the assistant keeps per-user memory across conversations. Optional display name via user_name in extra_body or X-User-Name. Headers win over body fields; X-* headers are Latin-1 only.
  • Sessions: pass a stable X-Session-Id header per conversation thread for best continuity.
  • Timezone: optional X-Timezone (IANA name) so times in answers match your user's clock.

10. Pricing

Per 1M tokens
Input$3.00
Output$10.00

Minimum 1¢ per request, maximum $5.00 per request, rounded half up. Generated files bill only the tokens spent building them — storage and downloads are free. Check spend per call with X-Include-Cost: 1, or on the dashboard.

11. Rate limits

  • 60 requests / minute per key
  • 5 concurrent streams per key
  • 25 active keys, 5 key creations / hour

Exceeding limits returns 429 rate_limit_exceeded.

12. Errors

Standard OpenAI error envelope:

{"error": {"message": "...", "type": "...", "code": "..."}}
json
CodeHTTPMeaning
invalid_api_key401Missing/unknown/revoked key
insufficient_balance402Top up your balance
invalid_modalities400modalities malformed or missing "text"
unsupported_url_scheme400Remote URL passed as attachment
invalid_file_format400Unsupported upload type
av_hit422Upload failed malware scan
max_keys_reached40925-key limit
rate_limit_exceeded429Slow down
stream_interrupted5xx (in-stream)Relay broke mid-stream — retry
internal_error500Our fault — retry with backoff

In streams, errors arrive as a data: {"error": {...}} frame followed by [DONE].

13. Support

Questions, higher limits, enterprise: [email protected] — or the chat on sentx.ai.