Consuming the API¶
Once a project has an endpoint and a key, your applications talk to it through the OpenAI-compatible chat completions API. This is the only protocol customer applications use — if your code already talks to OpenAI, it already talks to Adapta.
The three things you need¶
| Thing | Where it comes from | Used as |
|---|---|---|
| Base URL | Your server, e.g. http://your-server:8000/v1 |
OpenAI client base_url |
| Endpoint slug | The Endpoint tab in the console | the model field |
Scoped key (adp_…) |
The Keys tab (shown once) | the api_key |
Python (OpenAI SDK)¶
from openai import OpenAI
client = OpenAI(
base_url="http://your-server:8000/v1",
api_key="adp_xxxx…", # scoped to one project endpoint
)
resp = client.chat.completions.create(
model="support-kb-a1b2c3d4", # your endpoint slug (from the console)
messages=[{"role": "user", "content": "What is our refund window?"}],
)
print(resp.choices[0].message.content)
curl¶
curl http://your-server:8000/v1/chat/completions \
-H "Authorization: Bearer adp_xxxx…" \
-H "Content-Type: application/json" \
-d '{
"model": "support-kb-a1b2c3d4",
"messages": [{"role": "user", "content": "What is our refund window?"}]
}'
What's different from vanilla OpenAI¶
- The key picks the endpoint, not the
modelfield. Eachadp_key is bound to exactly one endpoint. Themodelslug you pass must match the key's endpoint — a mismatched slug is rejected (403). This means a key can never reach an endpoint it wasn't issued for. - Answers carry citations when the project has documents. If the project has indexed documents (a Knowledge project, or a fine-tune project that also uploaded documents), the response is grounded in them and includes the source chunks it used.
- Usage is metered. Every response includes
prompt_tokens,completion_tokens, andtotal_tokens, and is rolled up per day (visible in the console's Usage tab). - Fine-tune endpoints serve base + adapter. A fine-tune project's endpoint applies your trained LoRA adapter on top of the base model transparently — the request shape is identical. This applies equally to SFT and DPO adapters; the serving interface does not change based on how the adapter was trained. If that project also indexed documents, retrieval and the adapter compose in the same call (see Knowledge + behavior together).
Images (vision endpoints)¶
An endpoint whose project was created on a vision base model accepts the
standard OpenAI image content-parts — the image inline as a base64 data: URL:
import base64
with open("invoice.png", "rb") as f:
data_url = "data:image/png;base64," + base64.b64encode(f.read()).decode()
resp = client.chat.completions.create(
model="invoice-reader-a1b2c3d4",
messages=[{"role": "user", "content": [
{"type": "image_url", "image_url": {"url": data_url}},
{"type": "text", "text": "Extract vendor, date and total as JSON."},
]}],
)
Rules (v1, all violations come back as typed 4xx errors, never a crash):
- Inline
data:URLs only — the server never fetches remote image URLs. - png, jpeg or webp; ≤ 10 MB and ≤ 8192 px per image; ≤ 4 images per request.
- Requests with images are non-streaming (
streammust be false) and skip document retrieval — text-only requests on the same endpoint still answer from indexed documents with citations. - Sending an image to a text endpoint returns a clear
400— create the project on a vision base instead.
Streaming¶
Set "stream": true (or stream=True in the SDK) to receive tokens as
server-sent events, the same as the OpenAI streaming protocol. The final chunk
carries the usage totals. (Not available for requests carrying images — see above.)
Errors¶
Errors come back in a consistent envelope with a correlation_id:
If you need to report a problem, the correlation_id lets an operator find the
exact request in the server logs. No internal details (stack traces, library
errors) are ever exposed in the response.
The full request/response schema for every endpoint is in the API reference, generated from the live OpenAPI spec.