Skip to main content

OpenAI Responses API

SkillFlaw includes an endpoint compatible with the OpenAI Responses API at POST /api/v1/responses.

This route lets you reuse OpenAI client libraries with minimal changes:

  • set the OpenAI client base_url / baseURL to your SkillFlaw server's /api/v1/
  • send authentication in the x-api-key header
  • replace the OpenAI model value with a SkillFlaw flow ID or published endpoint name

Prerequisites

To run a flow through /api/v1/responses, the current backend requires all of the following:

  • Chat Input: the flow must contain a ChatInput or Chat Input node
  • Chat Output: the flow must contain a ChatOutput or Chat Output node
  • Authentication: requests must include a valid x-api-key
  • Model resolution: model must be a valid flow UUID or published endpoint name
  • Tools: tools must be omitted or set to null; any non-null value returns an OpenAI-style error with code tools_not_supported

Additional configuration for OpenAI client libraries

OpenAI SDKs require an api_key value even though SkillFlaw actually authenticates with x-api-key. In client code, set a dummy api_key and pass the real SkillFlaw API key through default headers.

In the following examples, replace SKILLFLAW_URL, SKILLFLAW_API_KEY, and FLOW_ID with values from your deployment.


_14
from openai import OpenAI
_14
_14
client = OpenAI(
_14
base_url="SKILLFLAW_URL/api/v1/",
_14
default_headers={"x-api-key": "SKILLFLAW_API_KEY"},
_14
api_key="dummy-api-key" # Required by the OpenAI SDK but ignored by SkillFlaw
_14
)
_14
_14
response = client.responses.create(
_14
model="FLOW_ID",
_14
input="There is an event that happens on the second Wednesday of every month. What are the event dates in 2026?",
_14
)
_14
_14
print(response.output_text)

Response

_14
Here are the event dates for the second Wednesday of each month in 2026:
_14
- January 14, 2026
_14
- February 11, 2026
_14
- March 11, 2026
_14
- April 8, 2026
_14
- May 13, 2026
_14
- June 10, 2026
_14
- July 8, 2026
_14
- August 12, 2026
_14
- September 9, 2026
_14
- October 14, 2026
_14
- November 11, 2026
_14
- December 9, 2026
_14
If you need these in a different format or want a downloadable calendar, let me know!

Example request


_10
curl -X POST \
_10
"$SKILLFLAW_URL/api/v1/responses" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-H "Content-Type: application/json" \
_10
-d '{
_10
"model": "$FLOW_ID",
_10
"input": "Hello, how are you?",
_10
"stream": false
_10
}'

Headers

HeaderRequiredDescriptionExample
x-api-keyYesYour SkillFlaw API key for authentication"sk-..."
Content-TypeYesSpecifies the JSON format"application/json"
X-SKILLFLAW-GLOBAL-VAR-*NoRequest-scoped variables exposed to the flow runtime"X-SKILLFLAW-GLOBAL-VAR-TRACE-ID: trace-123"

Request body

FieldTypeRequiredDefaultDescription
modelstringYes-The flow ID or published endpoint name to execute.
inputstringYes-The input text to process.
streambooleanNofalseWhether to stream the response.
backgroundbooleanNofalseAccepted for compatibility, but requests are still processed inline.
toolslist[Any]NonullMust be omitted or null. Non-null values return an invalid_request_error.
previous_response_idstringNonullSession identifier used for conversation continuity. See Continue conversations with response and session IDs.
includelist[string]NonullAdditional response data to include, such as ['tool_call.results']. For more, see Retrieve tool call results.

Example response


_35
{
_35
"id": "e5e8ef8a-7efd-4090-a110-6aca082bceb7",
_35
"object": "response",
_35
"created_at": 1756837941,
_35
"status": "completed",
_35
"model": "ced2ec91-f325-4bf0-8754-f3198c2b1563",
_35
"output": [
_35
{
_35
"type": "message",
_35
"id": "msg_e5e8ef8a-7efd-4090-a110-6aca082bceb7",
_35
"status": "completed",
_35
"role": "assistant",
_35
"content": [
_35
{
_35
"type": "output_text",
_35
"text": "Hello! I'm here and ready to help. How can I assist you today?",
_35
"annotations": []
_35
}
_35
]
_35
}
_35
],
_35
"parallel_tool_calls": true,
_35
"previous_response_id": null,
_35
"reasoning": {"effort": null, "summary": null},
_35
"store": true,
_35
"temperature": 1.0,
_35
"text": {"format": {"type": "text"}},
_35
"tool_choice": "auto",
_35
"tools": [],
_35
"top_p": 1.0,
_35
"truncation": "disabled",
_35
"usage": null,
_35
"user": null,
_35
"metadata": {}
_35
}

Response body

The response mixes SkillFlaw runtime data with OpenAI-compatible default fields.

The compatibility defaults shown above are currently fixed by the backend and cannot be overridden through the request body.

One important implementation detail: the response id is the conversation session identifier. If you omit previous_response_id, SkillFlaw generates a new UUID and uses it as the response id.

Fields set dynamically by SkillFlaw:

FieldTypeDescription
idstringSession identifier used as the OpenAI-compatible response ID.
created_atintUnix timestamp of response creation.
modelstringEchoes the request's model value, which can be a flow ID or a published endpoint name.
outputlist[dict]Output items such as assistant messages and optional tool-call records.
previous_response_idstringThe request's previous response/session identifier, if one was supplied.
Fields with OpenAI-compatible default values
FieldTypeDefault ValueDescription
objectstring"response"Always "response".
statusstring"completed"Response status: "completed", "in_progress", or "failed".
errordictnullError details (if any).
incomplete_detailsdictnullIncomplete response details (if any).
instructionsstringnullResponse instructions (if any).
max_output_tokensintnullMaximum output tokens (if any).
parallel_tool_callsbooleantrueWhether parallel tool calls are enabled.
reasoningdict{"effort": null, "summary": null}Reasoning information with effort and summary.
storebooleantrueWhether response is stored.
temperaturefloat1.0Temperature setting.
textdict{"format": {"type": "text"}}Text format configuration.
tool_choicestring"auto"Tool choice setting.
toolslist[dict][]Available tools.
top_pfloat1.0Top-p setting.
truncationstring"disabled"Truncation setting.
usagedictnullUsage statistics (if any).
userstringnullUser identifier (if any).
metadatadict{}Additional metadata.

Example streaming request

When you set "stream": true, SkillFlaw returns a Server-Sent Events stream. The stream includes OpenAI-compatible response.chunk payloads and ends with data: [DONE]. If the flow emits tool calls, the stream can also include event: frames such as response.output_item.added and response.function_call_arguments.delta before the final completion chunk.


_10
curl -X POST \
_10
"$SKILLFLAW_URL/api/v1/responses" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-H "Content-Type: application/json" \
_10
-d '{
_10
"model": "$FLOW_ID",
_10
"input": "Tell me a story about a robot",
_10
"stream": true
_10
}'

Result

_10
{
_10
"id": "f7fcea36-f128-41c4-9ac1-e683137375d5",
_10
"object": "response.chunk",
_10
"created": 1756838094,
_10
"model": "ced2ec91-f325-4bf0-8754-f3198c2b1563",
_10
"delta": {
_10
"content": "Once"
_10
},
_10
"status": null
_10
}

Streaming response body

FieldTypeDescription
idstringUnique response identifier.
objectstringAlways "response.chunk".
createdintUnix timestamp of chunk creation.
modelstringEchoes the request's model value, which can be a flow ID or a published endpoint name.
deltadictThe new content chunk.
statusstringResponse status: "completed", "in_progress", or "failed" (optional).

The stream continues until a final chunk with "status": "completed" indicates the response is finished.

Final completion chunk

_10
{
_10
"id": "f7fcea36-f128-41c4-9ac1-e683137375d5",
_10
"object": "response.chunk",
_10
"created": 1756838094,
_10
"model": "ced2ec91-f325-4bf0-8754-f3198c2b1563",
_10
"delta": {},
_10
"status": "completed"
_10
}

Continue conversations with response and session IDs

SkillFlaw uses previous_response_id as the conversation session identifier.

  • If you omit it, SkillFlaw creates a new UUID and returns that value as id.
  • If you provide it, SkillFlaw reuses that string as the session ID for the run.
  • You can therefore reuse the id returned by the previous response, or provide your own stable session key.

First Message:


_10
curl -X POST \
_10
"$SKILLFLAW_URL/api/v1/responses" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-H "Content-Type: application/json" \
_10
-d '{
_10
"model": "$FLOW_ID",
_10
"input": "Hello, my name is Alice"
_10
}'

Result

_23
{
_23
"id": "c45f4ac8-772b-4675-8551-c560b1afd590",
_23
"object": "response",
_23
"created_at": 1756839042,
_23
"status": "completed",
_23
"model": "ced2ec91-f325-4bf0-8754-f3198c2b1563",
_23
"output": [
_23
{
_23
"type": "message",
_23
"id": "msg_c45f4ac8-772b-4675-8551-c560b1afd590",
_23
"status": "completed",
_23
"role": "assistant",
_23
"content": [
_23
{
_23
"type": "output_text",
_23
"text": "Hello, Alice! How can I assist you today?",
_23
"annotations": []
_23
}
_23
]
_23
}
_23
],
_23
"previous_response_id": null
_23
}

Follow-up message:


_10
curl -X POST \
_10
"$SKILLFLAW_URL/api/v1/responses" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-H "Content-Type: application/json" \
_10
-d '{
_10
"model": "ced2ec91-f325-4bf0-8754-f3198c2b1563",
_10
"input": "What's my name?",
_10
"previous_response_id": "c45f4ac8-772b-4675-8551-c560b1afd590"
_10
}'

Result

_23
{
_23
"id": "c45f4ac8-772b-4675-8551-c560b1afd590",
_23
"object": "response",
_23
"created_at": 1756839043,
_23
"status": "completed",
_23
"model": "ced2ec91-f325-4bf0-8754-f3198c2b1563",
_23
"output": [
_23
{
_23
"type": "message",
_23
"id": "msg_c45f4ac8-772b-4675-8551-c560b1afd590",
_23
"status": "completed",
_23
"role": "assistant",
_23
"content": [
_23
{
_23
"type": "output_text",
_23
"text": "Your name is Alice. How can I help you today?",
_23
"annotations": []
_23
}
_23
]
_23
}
_23
],
_23
"previous_response_id": "c45f4ac8-772b-4675-8551-c560b1afd590"
_23
}

Optionally, you can use your own session ID values for the previous_response_id:


_10
curl -X POST \
_10
"$SKILLFLAW_URL/api/v1/responses" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-H "Content-Type: application/json" \
_10
-d '{
_10
"model": "ced2ec91-f325-4bf0-8754-f3198c2b1563",
_10
"input": "What's my name?",
_10
"previous_response_id": "session-alice-1756839048"
_10
}'

Result

This example uses the same flow as the other previous_response_id examples, but the LLM had not yet been introduced to Alice in the specified session:


_23
{
_23
"id": "session-alice-1756839048",
_23
"object": "response",
_23
"created_at": 1756839048,
_23
"status": "completed",
_23
"model": "ced2ec91-f325-4bf0-8754-f3198c2b1563",
_23
"output": [
_23
{
_23
"type": "message",
_23
"id": "msg_session-alice-1756839048",
_23
"status": "completed",
_23
"role": "assistant",
_23
"content": [
_23
{
_23
"type": "output_text",
_23
"text": "I don't have access to your name unless you tell me. If you'd like, you can share your name, and I'll remember it for this conversation!",
_23
"annotations": []
_23
}
_23
]
_23
}
_23
],
_23
"previous_response_id": "session-alice-1756839048"
_23
}

Retrieve tool call results

When a flow emits tool calls, you can ask SkillFlaw to include raw tool results by adding "include": ["tool_call.results"] to the request payload.

Without the include parameter, tool calls return basic function call information, but not the raw tool results. For example:


_10
{
_10
"id": "fc_1",
_10
"type": "function_call",
_10
"status": "completed",
_10
"name": "evaluate_expression",
_10
"arguments": "{\"expression\": \"15*23\"}"
_10
},

To get the raw results of each tool execution, add include: ["tool_call.results"] to the request payload:


_10
curl -X POST \
_10
"$SKILLFLAW_URL/api/v1/responses" \
_10
-H "Content-Type: application/json" \
_10
-H "x-api-key: $SKILLFLAW_API_KEY" \
_10
-d '{
_10
"model": "FLOW_ID",
_10
"input": "Calculate 23 * 15 and show me the result",
_10
"stream": false,
_10
"include": ["tool_call.results"]
_10
}'

The response now includes the tool call's results. For example:


_10
{
_10
"id": "evaluate_expression_1",
_10
"type": "tool_call",
_10
"tool_name": "evaluate_expression",
_10
"queries": ["15*23"],
_10
"results": {"result": "345"}
_10
}

Result

_58
{
_58
"id": "a6e5511e-71f8-457a-88d2-7d8c6ea34e36",
_58
"object": "response",
_58
"created_at": 1756835379,
_58
"status": "completed",
_58
"error": null,
_58
"incomplete_details": null,
_58
"instructions": null,
_58
"max_output_tokens": null,
_58
"model": "ced2ec91-f325-4bf0-8754-f3198c2b1563",
_58
"output": [
_58
{
_58
"id": "evaluate_expression_1",
_58
"queries": [
_58
"15*23"
_58
],
_58
"status": "completed",
_58
"tool_name": "evaluate_expression",
_58
"type": "tool_call",
_58
"results": {
_58
"result": "345"
_58
}
_58
},
_58
{
_58
"type": "message",
_58
"id": "msg_a6e5511e-71f8-457a-88d2-7d8c6ea34e36",
_58
"status": "completed",
_58
"role": "assistant",
_58
"content": [
_58
{
_58
"type": "output_text",
_58
"text": "The result of 23 * 15 is 345.",
_58
"annotations": []
_58
}
_58
]
_58
}
_58
],
_58
"parallel_tool_calls": true,
_58
"previous_response_id": null,
_58
"reasoning": {
_58
"effort": null,
_58
"summary": null
_58
},
_58
"store": true,
_58
"temperature": 1.0,
_58
"text": {
_58
"format": {
_58
"type": "text"
_58
}
_58
},
_58
"tool_choice": "auto",
_58
"tools": [],
_58
"top_p": 1.0,
_58
"truncation": "disabled",
_58
"usage": null,
_58
"user": null,
_58
"metadata": {}
_58
}

Pass global variables to your flows in headers

You can pass request-scoped variables into the flow runtime with custom HTTP headers.

The /responses endpoint extracts headers with the format X-SKILLFLAW-GLOBAL-VAR-{VARIABLE_NAME} and places them into the request context for that run. These variables are available only during the current request and are not persisted.

This example passes three request-scoped values into the flow runtime:


_11
curl -X POST \
_11
"$SKILLFLAW_URL/api/v1/responses" \
_11
-H "x-api-key: $SKILLFLAW_API_KEY" \
_11
-H "Content-Type: application/json" \
_11
-H "X-SKILLFLAW-GLOBAL-VAR-OPENAI_API_KEY: sk-..." \
_11
-H "X-SKILLFLAW-GLOBAL-VAR-USER_ID: user123" \
_11
-H "X-SKILLFLAW-GLOBAL-VAR-TRACE-ID: trace-123" \
_11
-d '{
_11
"model": "your-flow-id",
_11
"input": "Hello"
_11
}'

Result

_23
{
_23
"id": "4a4d2f24-bb45-4a55-a499-0191305264be",
_23
"object": "response",
_23
"created_at": 1756839935,
_23
"status": "completed",
_23
"model": "ced2ec91-f325-4bf0-8754-f3198c2b1563",
_23
"output": [
_23
{
_23
"type": "message",
_23
"id": "msg_4a4d2f24-bb45-4a55-a499-0191305264be",
_23
"status": "completed",
_23
"role": "assistant",
_23
"content": [
_23
{
_23
"type": "output_text",
_23
"text": "Hello! How can I assist you today?",
_23
"annotations": []
_23
}
_23
]
_23
}
_23
],
_23
"previous_response_id": null
_23
}

Variables passed with X-SKILLFLAW-GLOBAL-VAR-{VARIABLE_NAME} are available to the current run even if they are not stored in the database.

If a flow references variables that aren't available through request headers or the database, execution fails by default. To relax that behavior, set FALLBACK_TO_ENV_VARS=true so unresolved variables can fall back to .env values.

In the example above, the runtime first uses the request headers. If a variable is still unresolved and FALLBACK_TO_ENV_VARS=true, SkillFlaw can continue with environment-backed values; otherwise the run fails.