Skip to content

OpenAI-compatible API

This document describes the chat completion proxy exposed by the DIMARC gateway, compatible with the OpenAI specification. It is meant to be plugged as-is into automation tools that speak to an “OpenAI API spec compatible” provider — the most common target being an AI Agent module in Make.

  • An active DIMARC account.
  • Administrator status in your organization.
  • Your authentication token (see Authentication below).
https://api.dimarc.ai/openai/v1

Use this versioned base (/v1) in your tools’ configuration: it matches the convention expected by OpenAI SDKs and connectors (which expect a base like https://api.openai.com/v1). The unversioned prefix https://api.dimarc.ai/openai responds in exactly the same way — kept for integrations that normalize their own base URL by appending /v1 — but it is not the one to enter.

Retrieve a token via GET /v2/token (see Authentication to obtain your client_id/client_secret):

Fenêtre de terminal
curl --location 'https://api.dimarc.ai/v2/token?client_id=your-client-id&client_secret=your-client-secret'
{
"access_token": "**************",
"token_type": "x-api-key",
"expires_in": "3600"
}

Without a valid credential, any request returns 401:

{
"error": {
"message": "Missing API key. Provide it in the Authorization header as 'Bearer <key>'.",
"type": "invalid_request_error",
"code": "invalid_api_key"
}
}

If API access is disabled for your organization, the request returns 403 (type: "permission_error", code: "access_denied").

Identifier Description
dimarc-large Default model, best quality
dimarc-small Faster/cheaper model

These are aliases: the model actually served behind the scenes can change without notice, without breaking your integrations. An identifier outside this list is rejected with 400; an alias from the list that is momentarily not served returns 503 — a temporary outage, not a fault in your request. Query GET /openai/v1/models for the current list:

Fenêtre de terminal
curl 'https://api.dimarc.ai/openai/v1/models' \
--header 'Authorization: Bearer <your_access_token>'
{
"object": "list",
"data": [
{ "id": "dimarc-large", "object": "model", "created": 1732000000, "owned_by": "dimarc" },
{ "id": "dimarc-small", "object": "model", "created": 1732000000, "owned_by": "dimarc" }
]
}
  1. In your scenario, add an AI Agent module.
  2. As the LLM provider, choose OpenAI API spec compatible.
  3. Set the Base URL to: https://api.dimarc.ai/openai/v1.
  4. Set the API Key to the access_token value obtained above (see the token_type warning above — Make will send it as Authorization: Bearer).
  5. Choose the model: dimarc-large or dimarc-small.
  6. If your agent should trigger Make modules, attach them as tools: a call that results in a tool call returns finish_reason: "tool_calls", which triggers the module’s execution.
POST /openai/v1/chat/completions
Fenêtre de terminal
curl 'https://api.dimarc.ai/openai/v1/chat/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <your_access_token>' \
--data '{
"model": "dimarc-large",
"messages": [
{ "role": "user", "content": "Summarize this text in one sentence: ..." }
]
}'
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"model": "dimarc-large",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "..." },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 42, "completion_tokens": 18, "total_tokens": 60 }
}
Fenêtre de terminal
curl 'https://api.dimarc.ai/openai/v1/chat/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <your_access_token>' \
--data '{
"model": "dimarc-large",
"messages": [
{ "role": "user", "content": "What is the weather like in Lyon?" }
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Gives the current weather for a city",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
}
]
}'
{
"choices": [
{
"message": {
"role": "assistant",
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": { "name": "get_weather", "arguments": "{\"city\":\"Lyon\"}" }
}
]
},
"finish_reason": "tool_calls"
}
]
}
Fenêtre de terminal
curl 'https://api.dimarc.ai/openai/v1/chat/completions' \
--no-buffer \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <your_access_token>' \
--data '{
"model": "dimarc-large",
"messages": [{ "role": "user", "content": "Hello" }],
"stream": true
}'

Streamed text/event-stream response, terminated by data: [DONE]:

data: {"id":"chatcmpl-abc123","choices":[{"delta":{"content":"Hello"}}]}
data: {"id":"chatcmpl-abc123","choices":[{"delta":{"content":"!"}}]}
data: [DONE]

If generation fails after the stream has started — model error, upstream connection loss, a prolonged silence from the model, or a generation cut short — the HTTP status is already 200: the incident is reported through an OpenAI-formatted error frame, followed by data: [DONE].

data: {"error":{"message":"The model backend returned an error.","type":"api_error","code":"upstream"}}
data: [DONE]

So treat a frame carrying error as an abnormal end of generation: the content received before it is partial. The message is constant: the technical detail stays on the DIMARC side.

messages (required), tools, tool_choice, temperature, top_p, max_completion_tokens, max_tokens, presence_penalty, frequency_penalty, stop, stream, stream_options, response_format.

chat_template_kwargs is also relayed when provided: it is an advanced parameter specific to the underlying engine. When absent, the gateway forces it to { "enable_thinking": false } to disable extended reasoning by default; provide it explicitly to re-enable it.

Accepted values: true (SSE stream), false, absent, or explicitly null (these last three are treated identically: a regular, non-streamed JSON response). Any other value (string, number, object…) is rejected:

{
"error": {
"message": "The 'stream' parameter must be a boolean.",
"type": "invalid_request_error",
"code": "invalid_value"
}
}

400. This rejection happens before any call to the model: no usage is billed.

Parameter Rejection condition
n Value strictly greater than 1 (only n: 1, the default, is accepted)
logprobs Any defined value
logit_bias Any defined value

These rejections return 400:

{
"error": {
"message": "The 'n' parameter is not supported.",
"type": "invalid_request_error",
"code": "unsupported_parameter"
}
}
  • Request size: 2 MB (2,097,152 bytes, measured on the Content-Length header). Beyond that, the gateway returns 413 (code: "request_too_large") before even reading the body. A request with a body that does not declare its length — a body sent in chunks (Transfer-Encoding: chunked) — is refused with 411 (code: "missing_content_length"): OpenAI SDKs and connectors like Make serialize their body and always declare that length.
  • Output tokens: capped at 8192 per response. Both max_completion_tokens (current name) and max_tokens (deprecated) are accepted and capped independently; a value above the cap is silently clamped to 8192 — this is not a rejection. If neither is provided, the response is bounded to 8192. When both are provided, max_completion_tokens wins.
  • Tokens: usage counts against the token quota included in your subscription, assessed on the calendar-month total across all billable channels (public API and public channel). Beyond it, overage is billed on usage, as on the rest of the public API.
  • Spending limit: your organization can set a monthly overage cap, in euros, from its subscription settings. Once reached, requests are refused with 429 (code: "spending_limit_reached") until the next period or until the cap is raised. With no cap set, no amount limit applies. The model list stays reachable so your client can still configure itself.
  • Concurrent generations: at least 4 per organization. Beyond that, 429 (code: "concurrent_limit_exceeded") — retry once a running generation completes.
  • Stream duration: 5 minutes. A stream exceeding that duration is interrupted — the error frame then data: [DONE] are emitted, and the tokens produced so far are billed.
  • Rate: 100 requests per minute per organization, across all of your tokens — obtaining a new token does not reset the counter. Beyond that, 429 with a Retry-After header (seconds until the next window):
{
"error": {
"message": "Rate limit reached. Please slow down your requests.",
"type": "rate_limit_error",
"code": "rate_limit_exceeded"
}
}

Unlike the rest of the DIMARC API ({status, code, error, detail} envelope), this endpoint strictly follows the OpenAI error format:

{
"error": {
"message": "...",
"type": "...",
"code": "..."
}
}
Status Code Type Case
400 model_not_found invalid_request_error Model identifier outside the GET /openai/v1/models list
400 unsupported_parameter invalid_request_error n > 1, logprobs, or logit_bias provided
400 invalid_value invalid_request_error stream is neither a boolean, absent, nor null
400 invalid_request invalid_request_error Invalid body: malformed JSON, messages missing or empty
401 invalid_api_key invalid_request_error API key missing or invalid
403 access_denied permission_error API access disabled for the organization, or organization without a subscription
404 not_found invalid_request_error Unknown path under /openai, or wrong HTTP method on a known path
411 missing_content_length invalid_request_error Request with a body and no usable Content-Length header
413 request_too_large invalid_request_error Request body larger than 2 MB
429 rate_limit_exceeded rate_limit_error More than 100 requests/minute for this organization
429 concurrent_limit_exceeded rate_limit_error Too many concurrent generations for this organization
429 spending_limit_reached insufficient_quota Organization spending limit reached
500 internal_error api_error Unexpected internal failure: retrying is unlikely to change anything. The technical detail is never returned, it stays on the DIMARC side
502 upstream api_error The model returned an error
503 unavailable api_error Temporary outage: model advertised but not served, unreachable, or an internal dependency failing — retry after the delay advertised by the Retry-After header
504 timeout api_error The model did not respond in time

For any questions regarding the OpenAI-compatible API, contact our support team at contact@dimarc.fr