Feedback on Chat Prompts in API: Decoupling Prompts from Models

The new chat prompts in API feature is a great step forward. However, I find the current design - where each prompt is tied to a specific model somewhat limiting when used programmatically.

For example, if I want to reuse a prompt across different models or in a multi-model chain, I should be able to fetch the prompt by its ID independently of the associated model. Tying prompts to models adds friction, especially when transitioning from a YAML-based system to the OpenAI-hosted prompt repository. While I understand that model association makes sense for testing via the dashboard (where a model picker is useful), this coupling becomes restrictive when using prompts as part of a service or within code.

It would be helpful to support model-agnostic prompt retrieval via the API to enable better prompt reuse and flexibility in production workflows.

If you mean reusable prompts, when providing a prompt ID and a model in a request, the provided model overrides the prompt settings.

This way you can still use the reusable prompt just for the inputs themselves.

Just make sure to use a non reasoning model as the stored parameter, as the reverse will leave a reasoning effort parameter that will cause incompatibility with other models and cannot be overrided.

What does a prompt store?

This is an apparent schema that would validate the creation of a prompt for a reasoning model, which you can only do in the playground site, even though they are scoped to a project like an API key would be.

A “name” field is also sent upon create.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "title": "PromptPresetUpdateRootParams",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "model",
    "instructions",
    "text",
    "reasoning"
  ],
  "properties": {
    "model": {
      "type": "string"
    },
    "instructions": {
      "type": "array",
      "minItems": 1,
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "type",
          "role",
          "content"
        ],
        "properties": {
          "type": {
            "const": "message"
          },
          "role": {
            "type": "string",
            "enum": [
              "assistant",
              "developer",
              "user"
            ]
          },
          "content": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "oneOf": [
                {
                  "required": [
                    "type",
                    "text"
                  ],
                  "properties": {
                    "type": {
                      "const": "input_text"
                    },
                    "text": {
                      "type": "string"
                    }
                  }
                },
                {
                  "required": [
                    "type",
                    "name"
                  ],
                  "properties": {
                    "type": {
                      "const": "input_variable"
                    },
                    "name": {
                      "type": "string"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    },
    "tools": {},
    "text": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "format",
        "verbosity"
      ],
      "properties": {
        "format": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "type"
          ],
          "properties": {
            "type": {
              "const": "text"
            }
          }
        },
        "verbosity": {
          "type": "string",
          "enum": [
            "high",
            "medium",
            "low"
          ]
        }
      }
    },
    "reasoning": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "effort"
      ],
      "properties": {
        "effort": {
          "type": "string",
          "enum": [
            "minimal",
            "low",
            "medium",
            "high"
          ]
        }
      }
    }
  }
}

Notably missing from a prompt settings:

  • max_output_tokens
  • max_tool_calls
  • include - enabling what is possible, like code tool
  • parallel_tool_calls: disable

The playground UI and “prompts” that can be saved is poor overall: cannot move messages over to the permanent multi-shot or move them at all, thus cannot add tool call examples, cannot construct the multiple developer messages your application might actually need to demonstrate as examples, cannot re-sort, Playground gives and sends the variables by adding them itself instead of utilizing the feature or showing them in ‘get code’…)

So we can see sampling parameters are not sent to its playground-only prompt API when using a reasoning model.

Stored return

However, the return object HAS top_p and temperature = 1

Notably returned:

  • the API login account that made
  • an “ephemeral”:“false”.
{
  "id": "pmpt_3333",
  "object": "prompt",
  "created_at": 1755939000,
  "creator_user_id": "user-555",
  "default_version": "2",
  "ephemeral": false,
  "instructions": [
    {
      "type": "message",
      "content": [
        {
          "type": "input_text",
          "text": "# Your Permanent Identity - "
        },
        {
          "type": "input_variable",
          "name": "ai_role_name"
        },
        {
          "type": "input_text",
          "text": "\n\n# User custom instructions\n\nPortray this identity or character fully:\n\n~~~~~ persona\n"
        },
        {
          "type": "input_variable",
          "name": "custom_instructions"
        },
        {
          "type": "input_text",
          "text": "\n~~~~~"
        }
      ],
      "role": "developer"
    }
  ],
  "is_default": true,
  "model": "gpt-5-mini",
  "name": "mini5 w variables",
  "prompt_type": "responses",
  "reasoning": {
    "effort": "low"
  },
  "temperature": 1.0,
  "text": {
    "format": {
      "type": "text"
    },
    "verbosity": "high"
  },
  "tool_choice": "auto",
  "tools": [
    {
      "type": "function",
      "description": "Trigger the generation of a random horoscope style fortune.",
      "name": "fortune",
      "parameters": {
        "type": "object",
        "properties": {
          "count": {
            "type": "number",
            "description": "number of results, range 1-3 fortunes returned from one call"
          }
        },
        "required": [
          "count"
        ],
        "additionalProperties": false
      },
      "strict": true
    }
  ],
  "top_p": 1.0,
  "updated_at": 1755941800,
  "version": "2",
  "version_creator_user_id": "555"
}

Giving you an idea of what "variables’ look like as an input type in a content list.


Can’t switch model type?

So now we answer the question: I stored the model as gpt-5-mini. What if I change it to gpt-4.1 as a model parameter?

Unsupported parameter: 'reasoning.effort' is not supported with this model.

Solution:

No solution.

"reasoning": null == fails

"reasoning": { "effort": null, "summary": null} == fails

"reasoning": {} == fails


There’s multiple layers of “validators” on the API endpoint, and this is likely one of several that disobey API Reference documentation and do not support sending null or an empty array.

I doubted, but: prompts as a place to store settings is this bad.

PS, why would anyone use “variables”. You know exactly the developer message that would have to take them already. Saving bandwidth for the backend powered by a 2400 baud modem? Those that can’t code can’t code this either.