Requests
Generate complete runnable files with node scripts/openai-api.mjs scaffold <approach>.
Responses API anatomy
{
"model": "gpt-6.1-sol",
"instructions": "Stable instructions.",
"input": "The user's message, or an array of input items.",
"reasoning": {"effort": "low"},
"max_output_tokens": 4000
}inputis a string, or an array of items:{role, content}messages (rolesuser,assistant,developer,system),function_call,function_call_output,reasoning.- Message content parts:
input_text,input_image(image_urlis a URL or a data URL),input_file; assistant parts areoutput_text.textandimage_urlare the Chat shapes. - Read
response.output_text, or walkresponse.output. max_output_tokens≥ 16, and it includes reasoning tokens.- There is no
systemfield: useinstructionsor a developer message.
Chat Completions (legacy surface)
client.chat.completions.create({model, messages, max_completion_tokens}). Read
choices[0].message.content. Convert to Responses with
node scripts/openai-api.mjs convert request.json: it maps messages, tools, tool_choice,
response_format, token limits and reasoning effort, and lists what has no equivalent (n,
stop, seed, penalties, logit_bias).
Streaming
stream: true yields typed events. Handle response.output_text.delta (delta),
response.completed (final response, with usage), response.incomplete, and error.
Structured outputs
Responses:
"text": {"format": {"type": "json_schema", "name": "sentiment", "strict": true, "schema": {
"type": "object",
"properties": {"sentiment": {"type": "string", "enum": ["positive", "neutral", "negative"]}},
"required": ["sentiment"], "additionalProperties": false}}}SDK helpers do this from a type: TypeScript zodTextFormat(Schema, "name") with
client.responses.parse(...); Python client.responses.parse(..., text_format=PydanticModel).
Read response.output_parsed. Check status first, and handle a refusal part. Verified on all
29 probed models.
Images and files as input
{"type": "input_image", "image_url": "https://… or data:image/png;base64,…"} inside a user
message. Upload documents with client.files.create({file, purpose: "user_data"}) and reference
them as {"type": "input_file", "file_id": "file-…"}.
Embeddings
client.embeddings.create({model: "text-embedding-3-small", input: [...]}) returns 1536-dimension
vectors (text-embedding-3-large: 3072; pass dimensions to shorten). Compare with cosine
similarity. For retrieval without running your own index: create a vector store, add files, then
either search it directly or give the model the file_search tool.
Batches
Upload a JSONL file with one {custom_id, method: "POST", url: "/v1/responses", body} per line
(purpose: "batch"), then client.batches.create({input_file_id, endpoint: "/v1/responses", completion_window: "24h"}). Poll until status is completed, read the output file. About half
price. Results are unordered: match on custom_id. Completion can take hours: in this skill's
tests a two-request batch was still in_progress after 12 minutes.
Token counting
client.responses.inputTokens.count({model, input, instructions, tools}) (Python:
client.responses.input_tokens.count) returns input_tokens for free. Count on the model you
will call.