Skip to content

Chat completions

POST /chat/completions: the OpenAI-compatible endpoint that routes your conversation to any model in the catalog.

POSThttps://promptix.tn/api/v1/chat/completions

Creates a model response for a conversation. The endpoint follows the OpenAI Chat Completions API, so requests and responses have the same shape as with OpenAI, whichever provider serves the model.

Example

curl https://promptix.tn/api/v1/chat/completions \  -H "Authorization: Bearer $PROMPTIX_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "model": "openai/gpt-4o-mini",    "messages": [      { "role": "system", "content": "You are a concise assistant." },      { "role": "user", "content": "Give me three names for a café in Sidi Bou Said." }    ]  }'

Request body

Send JSON with Content-Type: application/json and your key in the Authorization header. Only model and messages are required.

request.jsonJSON
{  "model": "anthropic/claude-sonnet-4",  "messages": [    { "role": "system", "content": "You answer in French, in two sentences at most." },    { "role": "user", "content": "What is an API gateway?" }  ],  "temperature": 0.3,  "max_tokens": 300}
ParameterDescription
modelRequiredstringModel id from the catalog, for example openai/gpt-4o-mini or anthropic/claude-sonnet-4.
messagesRequiredarrayThe conversation so far. Each message has a role (system, user, assistant or tool) and a content (a string, or an array of content parts for multimodal models).
streamOptionalbooleanSend the answer as server-sent events. Default false. See Streaming.
max_tokensOptionalintegerMaximum number of tokens to generate. Set it to cap the cost of a request.
temperatureOptionalnumberSampling temperature between 0 and 2. Lower is more deterministic.
top_pOptionalnumberNucleus sampling, between 0 and 1. Change this or temperature, not both.
frequency_penaltyOptionalnumberBetween -2 and 2. Positive values discourage repeating the same tokens.
presence_penaltyOptionalnumberBetween -2 and 2. Positive values encourage new topics.
stopOptionalstring | string[]Up to four sequences where generation stops.
seedOptionalintegerBest-effort deterministic sampling on models that support it.
response_formatOptionalobject{ "type": "json_object" } for JSON output, or json_schema for structured output on models that support it.
toolsOptionalarrayFunctions the model may call, in the OpenAI tool format.
tool_choiceOptionalstring | objectauto, none, required, or a specific function.

Other parameters

Promptix validates model (a non-empty string) and messages (an array) and forwards every other field unchanged, so any OpenAI-compatible parameter can be sent. Support depends on the model: the model page in the catalog lists the parameters it accepts, and unsupported ones may be ignored. The usage field is reserved: Promptix sets it itself to measure cost.

Response

A non-streaming request returns a single JSON object:

200 OKJSON
{  "id": "gen-1758880023-kQ3vX8mZpL2nR7tW",  "object": "chat.completion",  "created": 1758880023,  "model": "openai/gpt-4o-mini",  "provider": "OpenAI",  "choices": [    {      "index": 0,      "finish_reason": "stop",      "message": {        "role": "assistant",        "content": "1. Café Bleu Jasmin\n2. Dar Nour\n3. Les Terrasses du Cap"      }    }  ],  "usage": {    "prompt_tokens": 31,    "completion_tokens": 22,    "total_tokens": 53  }}
FieldDescription
idGeneration id (gen-…). Use it with GET /generation to get the cost in TND.
objectchat.completion
createdUnix timestamp in seconds.
modelThe model that produced the answer.
providerThe upstream provider that served the request.
choices[].messageThe assistant message: role, content and, when the model calls tools, tool_calls.
choices[].finish_reasonstop, length (hit max_tokens), tool_calls or content_filter.
usageprompt_tokens, completion_tokens and total_tokens. These are the tokens you are billed for.

The response may contain extra fields from the upstream provider (for example native_finish_reason or additional usage details). Ignore fields you do not use. The amount charged to your balance is not in the response: look it up with GET /generation.

More examples

Multi-turn conversation

The API is stateless: send the whole conversation each time, including previous assistant answers. Every token you send is billed as a prompt token, so trim or summarize long histories.

request.jsonJSON
{  "model": "openai/gpt-4o-mini",  "messages": [    { "role": "system", "content": "You are a support assistant for an online shop in Tunis." },    { "role": "user", "content": "Do you deliver to Sfax?" },    { "role": "assistant", "content": "Yes, delivery to Sfax takes 2 to 3 working days." },    { "role": "user", "content": "And how much does it cost?" }  ]}

JSON output

Ask for JSON with response_format and describe the expected keys in the system message.

request.jsonJSON
{  "model": "openai/gpt-4o-mini",  "response_format": { "type": "json_object" },  "messages": [    { "role": "system", "content": "Extract the fields and reply with JSON: {\"city\": string, \"amount_tnd\": number}" },    { "role": "user", "content": "Invoice from Sousse, total due 245.500 dinars." }  ]}

Tool calling

Declare functions in tools. When the model decides to call one, the response has finish_reason: "tool_calls":

request.jsonJSON
{  "model": "openai/gpt-4o-mini",  "messages": [{ "role": "user", "content": "What is the weather in Bizerte?" }],  "tools": [    {      "type": "function",      "function": {        "name": "get_weather",        "description": "Current weather for a Tunisian city",        "parameters": {          "type": "object",          "properties": { "city": { "type": "string" } },          "required": ["city"]        }      }    }  ],  "tool_choice": "auto"}
response (excerpt)JSON
{  "choices": [    {      "index": 0,      "finish_reason": "tool_calls",      "message": {        "role": "assistant",        "content": null,        "tool_calls": [          {            "id": "call_7f3a",            "type": "function",            "function": { "name": "get_weather", "arguments": "{\"city\":\"Bizerte\"}" }          }        ]      }    }  ]}

Run the function in your code, then send its result back as a tool message with the matching tool_call_id. Send the same tools array again (omitted below for brevity):

follow-up requestJSON
{  "model": "openai/gpt-4o-mini",  "messages": [    { "role": "user", "content": "What is the weather in Bizerte?" },    {      "role": "assistant",      "content": null,      "tool_calls": [        { "id": "call_7f3a", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\":\"Bizerte\"}" } }      ]    },    { "role": "tool", "tool_call_id": "call_7f3a", "content": "{\"temp_c\": 24, \"sky\": \"clear\"}" }  ]}

Images

Models that accept images take an array of content parts. Check the model's input modalities in the catalog.

request.jsonJSON
{  "model": "openai/gpt-4o-mini",  "messages": [    {      "role": "user",      "content": [        { "type": "text", "text": "What is written on this sign?" },        { "type": "image_url", "image_url": { "url": "https://example.com/sign.jpg" } }      ]    }  ]}

Limits

  • Your balance must be at least 0.100 TND when the request starts, otherwise you get 402.
  • A key with a monthly limit that has been reached gets 402 with code key_monthly_limit.
  • A request, including a stream, can run for up to 300 seconds.
  • The context length depends on the model and is listed in the catalog. Prompts that are too long are rejected by the provider with a 400 or 413.

See Errors and limits for every status code.