Debug with a thunk's OpenAI-compatible chat API
Debugging only — not for production. Use this API to inspect a model your thunk can already call: try a prompt, compare wording, or list the environment's model names. Do not build a live product, widget, or partner integration on it. For production work, start a workflow with Inbound requests via a REST API, chat on a conversation input with the conversational REST API, or let another assistant call your thunk's tools by publishing the thunk as an MCP server.
Every thunk can answer a raw chat completion — the same OpenAI-style request a script or OpenAI-compatible client already knows how to send — against a model that thunk is already allowed to use. You do not start a workflow work item, and you do not open a conversation. The call uses the thunk's environment models, so you do not hand your own provider key to the caller.
Use this only while you are debugging. If you need a production integration, pick one of the APIs in the callout above.
What this API does — and does not do
This endpoint talks to the model and returns one completed chat-completions JSON object. It does not:
Create or update a work item
Run the thunk's playbook or AI instructions
Call the thunk's tools (even if you include a
toolslist — the model may suggest a tool call in the response, but Thunk.AI will not execute it)Stream tokens as they are generated (
stream: trueis rejected)
The model you send must be a name that the environment already offers. There is no silent substitute if you misspell it or pick a model that is not assigned.
1: Create an API key
API keys are the same keys used by the workflow and conversational REST APIs.
Go to Run → Inbound Requests → API Channel
Open API Keys
Create a key and copy it immediately — it is shown only once. Because this API is only for debugging, prefer a short-lived key (1 day or 1 week) and revoke it when you are done.
For screenshots and revoke steps, see Inbound requests via a REST API (Generate an API Key).
Keys use the thk_… prefix. Send them as either:
X-API-Key: {api-key}
or, if your client always sends a Bearer token (the OpenAI SDK does):
Authorization: Bearer {api-key}
The key must belong to the thunk in the URL. A key created for a different thunk is rejected.
2: Set the base URL
Replace {thunk_id} with your thunk's id:
https://postern.thunk.ai/api/thunk/{thunk_id}/llm/v1
That /v1 form is what an OpenAI-compatible client expects: chat.completions.create posts to /chat/completions, and models.list gets /models.
You can also call the same paths without /v1:
https://postern.thunk.ai/api/thunk/{thunk_id}/llm
3: List the models you can use
GET /models returns the model names this thunk's environment allows — the same names you would pick in the product.
curl -X GET \
'https://postern.thunk.ai/api/thunk/{thunk_id}/llm/v1/models' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {api-key}'
A successful response looks like:
{
"object": "list",
"data": [
{ "id": "gpt-4.1", "object": "model", "created": 0, "owned_by": "thunk" }
]
}
Use an id from this list as model on the next call. An empty data array means the environment answered and currently has no models assigned.
If the environment cannot list models, the API returns 503.
4: Send a chat completion
POST /chat/completions requires a JSON body with a string model and a messages array.
curl -X POST \
'https://postern.thunk.ai/api/thunk/{thunk_id}/llm/v1/chat/completions' \
-H 'accept: application/json' \
-H 'Authorization: Bearer {api-key}' \
-H 'Content-Type: application/json' \
-d '{
"model": "gpt-4.1",
"messages": [
{ "role": "user", "content": "Summarize this request in one sentence." }
]
}'
The response is a standard OpenAI chat-completions object (id, object, created, model, choices, usage, and related fields).
From an OpenAI-compatible SDK (local debugging)
If you already have an OpenAI-compatible client and want to poke the model from a notebook or script, point the client's base URL at the thunk /llm/v1 address and pass the thunk API key as the client's API key:
from openai import OpenAI
client = OpenAI(
api_key="thk_…",
base_url="https://postern.thunk.ai/api/thunk/{thunk_id}/llm/v1",
)
completion = client.chat.completions.create(
model="gpt-4.1",
messages=[{"role": "user", "content": "Summarize this request in one sentence."}],
)
print(completion.choices[0].message.content)
Do not set stream=True. This endpoint returns one finished JSON object.
Request limits
Required fields:
model(string) andmessages(array). Missing either is 400.No streaming. Omit
stream, or set it tofalse.Exact model name. It must match a name from
GET /models.Body size: at most 1 MB. For images, send
httpsURLs rather than embedded data URLs.n: at most 8.max_tokens/max_completion_tokens: at most 16,384. These must be whole numbers of 1 or more.
Usual OpenAI chat-completions fields such as temperature, tools, tool_choice, and response_format are accepted. Extra fields your client sends are ignored.
Errors you may see
400 — the body is missing
modelormessages,streamis true, a number field is not a whole number, or the model name is not available in this thunk's environment.401 — no usable API key, or it is invalid.
403 — the key is valid but is not allowed on this thunk (for example, it belongs to a different thunk).
404 — the thunk was not found.
413 — the JSON body is larger than 1 MB.
429 — too many requests; wait and retry.
503 — the thunk's environment could not list or reach its models.
Choosing this API vs the other inbound APIs
Goal | Use |
Debug a model this thunk can use (not for production) | This article |
Create / poll structured workflow work items | |
Chat turns on a workflow conversation | |
Let another AI assistant call your thunk's tools |
