> This page is for Gateway.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.merge.dev/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.merge.dev/_mcp/server.

# Create response

POST https://api-gateway.merge.dev/v1/responses
Content-Type: application/json

Create an LLM response in Gateway's native Responses shape. This is not OpenAI's
Responses API: clients that implement it (the OpenAI SDK's `client.responses.*`,
Codex) should use `POST /v1/openai/responses`, or send `X-Merge-Wire-Format: openai`
on this endpoint to receive the OpenAI shape. Codex is detected by its `originator`
header and served the OpenAI shape automatically.

OpenAI-only request fields with a native equivalent are translated
(`instructions` → leading system message, `reasoning.effort` → reasoning effort,
`text.format` → `response_format`, `max_output_tokens` → `max_tokens`); any other
OpenAI-only field is ignored and reported in `warnings` with code
`openai_fields_ignored`.


Reference: https://docs.merge.dev/merge-gateway/api-overview/responses/create

## Authentication

- `Authorization` header (bearer token, required) — Your production key sent as a bearer token.

## Request

### Body (application/json)

This endpoint expects a ResponseRequest.

- `input` (list of ResponseRequestInputItems, required) — Conversation history
- `model` (string, optional, nullable) — Model ID as `provider/model-name` or a bare name, an `@alias/<slug>` model alias, or `default_routing`; optional when a routing policy applies.
- `customer` (string, optional, nullable) — Customer ID (UUID) to scope this request to, applying that customer's routing policy, provider keys, budget, and usage attribution. A non-UUID value returns 422 and an unknown customer returns 404 `customer_not_found`.
- `routing_policy_id` (string, optional, nullable) — Routing policy ID for this request: an org-level policy, or a project or customer policy when the request carries that scope.
- `priority_order` (list of ResponseRequestPriorityOrderItems, optional, nullable) — An inline PRIORITY list: the models to try for this request in order, first success wins. Each entry is a model id (`provider/model` or a bare name) or a `{model, priority, vendors}` object. Up to 10 entries. Bypasses every stored routing policy (org default, customer default, key binding) while the key's allowed models, vendor and region limits, ZDR and vendor access still apply per entry. Fails over on provider faults only (5xx, 429, timeouts, 402); on a stream, before the first byte. The list is materialized as a routing policy with an id derived from its content and scope, attributed in `routing.policy_id` and the `x-merge-routing-policy-id` header, and reusable later via `routing_policy_id`. `model` must be omitted or equal the first entry. Cannot be combined with `routing_policy_id`, a policy alias, or the top-level `vendor` / `vendors` pins. Also accepted on every SDK-compatible surface. See [Sending a priority list with the request](/merge-gateway/routing/using-policies#sending-a-priority-list-with-the-request).
- `tools` (list of ResponseRequestToolsItems, optional, nullable) — Tools the model may call: function tools, or provider-native tools passed through by `type`.
- `tool_choice` (ResponseRequestToolChoice, optional, nullable) — Tool choice policy: 'auto', 'none', 'required', or \{'type': 'function', 'function': \{'name': '...'}}
- `max_tokens` (integer, optional, nullable) — Maximum tokens to generate
- `temperature` (double, optional, nullable) — Sampling temperature
- `top_p` (double, optional, nullable) — Nucleus sampling parameter
- `stop` (list of string, optional, nullable) — Stop sequences
- `response_format` (ResponseRequestResponseFormat, optional, nullable) — Response format (json_object or json_schema structured output)
- `stream` (boolean, optional, default: false) — Whether to stream the response
- `tags` (list of TagInput, optional, nullable) — Tags to attach to this request for categorization (key-value pairs)
- `project_id` (string, optional, nullable) — Optional project ID (UUID) to associate with this request
- `include_routing_metadata` (boolean, optional, default: false) — Include detailed routing metadata in response
- `include_guardrails_metadata` (boolean, optional, default: false) — Include prompt-injection protection and DLP results for this request in a top-level `guardrails` object. In prompt-injection alert mode this also runs the direct scan on the request path (bounded by the alert-mode budget) so the score is available in the body; requests without the flag are unaffected.
- `vendor` (string, optional, nullable) — Restrict routing to a specific vendor (hosting platform)
- `vendors` (list of string, optional, nullable) — Ordered list of acceptable vendors. First available wins.
- `service_tier` (enum, optional, nullable) — Processing tier: `standard` (default), `flex`, `priority` (`fast` is an alias), or `ultrafast` (OpenAI only), where `default`, `auto`, `unspecified`, and `standard_only` also mean standard; a tier the route doesn't price returns 400 `unsupported_params`.
  - Allowed values: `standard`, `flex`, `priority`, `fast`, `ultrafast`, `default`, `auto`, `unspecified`, `standard_only`
- `service_tier_fallback` (boolean, optional, default: false) — If the provider throttles the requested tier (429/503), retry once at the standard tier, billed at standard rates. The response service_tier shows the tier that actually served.
- `previous_response_id` (string, optional, nullable) — ID of a stored response (`resp_...`) whose conversation is replayed before this request's `input`; an expired or unknown ID returns 404 `response_not_found`.
- `store` (boolean, optional, nullable) — Set `true` to store this turn so a later request can continue it with `previous_response_id`; stored turns expire an hour after their last use and are never kept under zero data retention.
- `logprobs` (boolean, optional, nullable) — Return log probabilities of the output tokens.
- `top_logprobs` (integer, optional, nullable) — Number of most likely tokens to return per position; requires `logprobs`.
- `user` (string, optional, nullable) — End-user identifier forwarded to the provider.
- `safety_identifier` (string, optional, nullable) — End-user identifier forwarded to providers that support it (OpenAI's newer name for `user`).
- `prompt_cache_retention` (string, optional, nullable) — Prompt-cache retention hint forwarded to OpenAI.
- `parallel_tool_calls` (boolean, optional, nullable) — Whether the model may make several tool calls in one turn; omit to keep the provider default.
- `modalities` (list of enum, optional, nullable) — Output modalities to generate; include `image` for inline image generation on a route that supports image output, otherwise the request returns 400.
  - Allowed values: `text`, `image`
- `cache_control` (map from string to any, optional, nullable) — Top-level prompt-caching setting for providers that cache automatically.
- `session_id` (string, optional, nullable) — Caching session hint, up to 256 characters, also accepted as the `X-Session-Id` header, which wins when both are set.
- `thinking` (ThinkingConfig, optional, nullable) — Extended thinking settings; the model can reason between tool calls.
- `provider_options` (map from string to any, optional, nullable) — Provider-specific options, keyed by provider family.
- `fusion` (FusionConfig, optional, nullable) — Multi-model fusion settings, used when `model` is `fusion`.

## Response

### 200

Successful Response

- `id` (string, required)
- `created_at` (datetime, required)
- `model` (string, required) — The model that generated the response, in 'provider/model-name' format
- `output` (list of OutputMessage, required)
- `usage` (Usage, required) — Token usage statistics.
- `object` ("response", optional, default: response)
- `vendor` (string, optional, nullable) — The execution vendor that served the request
- `provider_request_id` (string, optional, nullable) — The upstream provider's request ID
- `routing` (RoutingMetadata, optional, nullable) — Routing metadata (only present when include_routing_metadata=true)
- `guardrails` (GuardrailsMetadata, optional, nullable) — Prompt-injection protection and DLP results (only present when include_guardrails_metadata=true). Also present on blocked 422 responses beside `error`.
- `service_tier` (string, optional, nullable) — The tier that actually served the request and was billed. Differs from the requested tier on a throttle fallback.

## Errors

### 422 Unprocessable Entity Error

Validation Error

- `detail` (list of ValidationError, optional)

## Types

### ResponseRequestInputItems

- `type`: `message` (MessageInput)
  - `content` (ResponseRequestInputItemsDiscriminatorMappingMessageContent, required)
  - `role` (enum, required) — The role of the message author. `developer` is accepted as an alias for `system` (matching the OpenAI Responses API) and is treated as `system`
    - Allowed values: `system`, `user`, `assistant`, `developer`
  - `cache_control` (map from string to any, optional, nullable) — Marks a prompt-caching breakpoint at this block for providers that support it.
- `type`: `tool_result` (ToolResultInput)
  - `content` (ToolResultInputContent, required)
  - `tool_use_id` (string, required)
  - `cache_control` (map from string to any, optional, nullable) — Marks a prompt-caching breakpoint at this block for providers that support it.

### ResponseRequestPriorityOrderItems

### ResponseRequestToolsItems

### ResponseRequestToolChoice

Tool choice policy: 'auto', 'none', 'required', or \{'type': 'function', 'function': \{'name': '...'}}

### ResponseRequestResponseFormat

Response format (json_object or json_schema structured output)

### TagInput

Tag key-value pair for use in requests.

- `key` (string, required) — Tag key
- `value` (string, required) — Tag value

### ThinkingConfig

Extended thinking settings.

- `type` (enum, optional, default: enabled) — Turn extended thinking on or off.
  - Allowed values: `enabled`, `disabled`
- `budget_tokens` (integer, optional, nullable) — Maximum tokens the model may spend thinking.

### FusionConfig

Sends the prompt to every `analysis_models` entry in parallel, then has `synthesis_model` merge the answers into one response.

- `analysis_models` (list of string, required) — Two or more model IDs that answer the prompt in parallel.
- `synthesis_model` (string, optional, nullable) — Model that merges the parallel answers into the final response; defaults to the first `analysis_models` entry.
- `synthesis_instructions` (string, optional, nullable) — Replaces the default instruction given to the synthesis model.
- `preset` (enum, optional, default: quality) — Preset name, accepted for compatibility and currently advisory.
  - Allowed values: `quality`, `budget`
- `include_candidates` (boolean, optional, default: true) — Include each parallel answer's text and usage in the response's `fusion` metadata.

### OutputMessage

An output message from the assistant.

- `id` (string, required)
- `content` (list of OutputMessageContentItems, required)
- `type` ("message", optional, default: message)
- `role` ("assistant", optional, default: assistant)
- `finish_reason` (enum, optional, nullable)
  - Allowed values: `stop`, `max_tokens`, `tool_use`, `content_filter`

### Usage

Token usage statistics.

- `input_tokens` (integer, required)
- `output_tokens` (integer, required)
- `total_tokens` (integer, required)
- `cost` (double, optional, nullable) — Cost of this call in USD, computed by Gateway. Null when the route that served the request has no pricing on file, so cost trackers record no spend rather than a false zero.

### RoutingMetadata

Metadata about how the request was routed.

- `policy_id` (string, optional, nullable)
- `policy_name` (string, optional, nullable)
- `strategy` (string, optional, nullable)
- `intelligent_routing_used` (boolean, optional, default: false)
- `complexity_score` (double, optional, nullable) — ML-computed prompt complexity score (0-1)
- `adjusted_score` (double, optional, nullable) — Strategy-adjusted complexity score
- `selected_tier` (integer, optional, nullable)
- `total_tiers` (integer, optional, nullable)
- `routing_reason` (string, optional, nullable) — Human-readable explanation of the routing decision
- `router_decision_id` (string, optional, nullable) — ID of the router decision, set only when a router ran.
- `model_requested` (string, optional, nullable)
- `model_used` (string, optional, nullable) — The actual model selected by routing
- `vendor_used` (string, optional, nullable) — Vendor that served the request.
- `credential_type` (string, optional, nullable) — Whose provider credential served the request: `byok` or `managed`.
- `fallback` (boolean, optional, default: false) — True when routing fell through to a lower-priority candidate; `model_used` and `vendor_used` show what served.
- `reasoning_effort_requested` (string, optional, nullable) — Reasoning effort the request asked for.
- `reasoning_effort_applied` (string, optional, nullable) — Reasoning effort sent to the provider.
- `reasoning_effort_source` (string, optional, nullable) — Where the applied reasoning effort came from.
- `cost_usd` (double, optional, nullable) — Estimated provider spend for the request in USD, at the list price of the route that served it, whoever paid the provider. On a BYOK key this is what the tokens cost on your own provider account. Null when the route has no pricing on file.
- `merge_fee_usd` (double, optional, nullable) — Merge's fee on this request in USD, at the markup rate that applies to your organization (the plan rate, or 0 when no markup applies). cost_usd + merge_fee_usd is the request's cost with markup on every key type. Excludes server-tool charges such as web search. Null when cost_usd is null.
- `latency` (RoutingLatency, optional, nullable) — Latency breakdown for routing steps.

### GuardrailsMetadata

Guardrail results attached when `include_guardrails_metadata` is set. Every field is a copy of a value already computed for the request log; no prompt text or matched value is ever included.

- `prompt_injection` (PromptInjectionMetadata, optional, nullable) — Prompt-injection protection outcome. Null when the organization has no prompt-injection configuration.
- `dlp` (DLPMetadata, optional, nullable) — DLP enforcement outcome. Null when DLP did not run for the request.

### ValidationError

Single field-level validation error. `loc` is the JSON path to the offending field, `msg` is a human-readable explanation, and `type` is a stable machine-readable error code.

- `loc` (list of ValidationErrorLocItems, required)
- `msg` (string, required)
- `type` (string, required)
- `input` (any, optional)
- `ctx` (ValidationErrorCtx, optional)

### ResponseRequestInputItemsDiscriminatorMappingMessageContent

### ToolResultInputContent

### PriorityOrderEntry

One entry of `priority_order`: a model, optionally pinned to vendors.

- `model` (string, required) — Model id, `provider/model` or a bare base name that resolves the same way `model` does.
- `priority` (integer, optional, nullable) — Lower tries first, as in the routing policies API's PRIORITY shape. Omit to use list order; explicit values sort ahead of list order.
- `vendors` (list of string, optional, nullable) — Pin this entry to these execution hosts, in order of preference. Omit to allow every vendor that serves the model. Must not be empty when sent.

### FunctionTool

A function tool that the model can call.

- `name` (string, required)
- `description` (string, required)
- `parameters` (map from string to any, required)
- `type` ("function", optional, default: function)
- `defer_loading` (boolean, optional, nullable) — Load this tool on demand through tool search instead of sending it with every request.

### ProviderNativeTool

A provider-native tool, passed through to the provider with all of its fields.

- `type` (string, optional, nullable) — Provider tool type, for example `web_search_20250305`.

### ResponseFormatJson

JSON response format configuration.

- `type` ("json_object", optional, default: json_object)

### ResponseFormatJsonSchema

JSON Schema response format configuration (for structured output).

- `json_schema` (JsonSchemaSpec, required) — The `json_schema` wrapper for structured output; omit `strict` to keep the provider's default, and unknown wrapper keys pass through to the provider.
- `type` ("json_schema", optional, default: json_schema)

### OutputMessageContentItems

- `type`: `text` (TextContent)
  - `text` (string, required)
  - `annotations` (list of map from string to any, optional, nullable) — Citations attached to this text, such as `url_citation` entries from web search.
  - `cache_control` (map from string to any, optional, nullable) — Marks a prompt-caching breakpoint at this block for providers that support it.
- `type`: `image_url` (ImageUrlContent)
  - `url` (string, required)
  - `cache_control` (map from string to any, optional, nullable) — Marks a prompt-caching breakpoint at this block for providers that support it.
- `type`: `image` (ImageContent)
  - `data` (string, required) — Base64-encoded image data or URL
  - `media_type` (string, required) — e.g. 'image/png', 'image/jpeg'
  - `cache_control` (map from string to any, optional, nullable) — Marks a prompt-caching breakpoint at this block for providers that support it.
  - `source_type` (enum, optional, default: base64)
    - Allowed values: `base64`, `url`
- `type`: `document` (DocumentContent)
  - `data` (string, required) — Base64-encoded content or URL
  - `media_type` (string, required) — e.g. 'application/pdf'
  - `cache_control` (map from string to any, optional, nullable) — Marks a prompt-caching breakpoint at this block for providers that support it.
  - `source_type` (enum, optional, default: base64)
    - Allowed values: `base64`, `url`
- `type`: `tool_use` (ToolUseContent)
  - `id` (string, required)
  - `input` (map from string to any, required)
  - `name` (string, required)

### RoutingLatency

Latency breakdown for routing steps.

- `policy_lookup_ms` (double, optional, default: 0)
- `routing_decision_ms` (double, optional, default: 0)
- `llm_call_ms` (double, optional, default: 0)
- `total_ms` (double, optional, default: 0)

### PromptInjectionMetadata

Prompt-injection protection outcome for the request.

- `mode` (enum, required) — The effective prompt-injection mode at evaluation time.
  - Allowed values: `off`, `alert`, `block`
- `action` (string, optional, nullable) — `observe` or `block`. Null when no direct scan ran.
- `blocked_reason` (string, optional, nullable) — Why the request was blocked, e.g. `pi_block_threshold`.
- `skipped_reason` (string, optional, nullable) — Why no Tier 1 score is present: `alert_timeout`, `block_timeout`, `saturated` (alert mode: every scan slot on the serving instance was busy, so the scan was skipped rather than queued), `no_segments`, `sidecar_error`, `sidecar_unavailable`, `deferred`.
- `score` (double, optional, nullable) — Maximum direct-injection (Tier 1) score across scanned segments, in [0, 1].
- `block_threshold` (double, optional, nullable) — The effective `pi_block_threshold` the score is compared against.
- `model_version` (string, optional, nullable) — Classifier version that produced the decisive score.
- `triggering_segment` (PITriggeringSegment, optional, nullable) — The segment behind the decisive score: the maximum in alert mode, the first over threshold in block mode.
- `segments` (list of PISegmentScore, optional) — Every input segment the scanner saw, by id and kind, with its score when scored.
- `allowlist_skipped_segment_ids` (list of string, optional) — Segments skipped because they matched an allowlist pattern.
- `indirect` (PIIndirectMetadata, optional, nullable) — Indirect-injection (untrusted content) signals for the request.
- `output` (PIOutputMetadata, optional, nullable) — Output-side credential scan. Non-streaming responses only.
- `policy_scope` (string, optional, nullable) — `org`, or `project` when a project override applied.
- `latency_ms` (double, optional, nullable) — Time the direct scan took, in milliseconds.

### DLPMetadata

DLP enforcement outcome for the request.

- `status` (enum, required)
  - Allowed values: `skipped`, `clean`, `flagged`, `redacted`, `blocked`, `error`
- `action` (enum, required)
  - Allowed values: `none`, `notify`, `redact`, `block`
- `skipped_reason` (string, optional, nullable) — Set when status is `skipped` or `error`: `no_enabled_rules`, `no_text`, `disabled`, `sidecar_timeout`, `sidecar_http_error`, `sidecar_exception`.
- `finding_count` (integer, optional, default: 0)
- `entity_counts` (map from string to integer, optional) — Findings per entity type, keyed by entity name (for example US_SSN). Never the matched values.
- `action_counts` (map from string to integer, optional) — Findings per rule action (`LOG`, `REDACT`, `BLOCK`).
- `rule_ids` (list of string, optional) — Your DLP rule ids that matched.
- `policy_scope` (string, optional, nullable) — `org`, or `project` when a project override applied.
- `latency_ms` (double, optional, nullable)

### ValidationErrorLocItems

### ValidationErrorCtx

### JsonSchemaSpec

The `json_schema` wrapper for structured output; omit `strict` to keep the provider's default, and unknown wrapper keys pass through to the provider.

- `schema` (map from string to any, required)
- `name` (string, optional, default: response)
- `description` (string, optional, nullable)
- `strict` (boolean, optional, nullable)

### PITriggeringSegment

The segment that produced the decisive score.

- `id` (string, required)
- `kind` (string, optional, nullable)
- `score` (double, optional, nullable)

### PISegmentScore

Direct-injection score for one scanned input segment. Identified by id and kind; never carries the text.

- `id` (string, required)
- `kind` (string, required) — `system_message`, `user_message`, `assistant_message`, `tool_result`, `tool_definition`, ...
- `trusted` (boolean, required)
- `score` (double, optional, nullable) — Maximum Tier 1 score for the segment; null when it was not scored.
- `lexical_hit` (boolean, optional, default: false) — True when the pattern-based detector fired on this segment.

### PIIndirectMetadata

Indirect-injection signals for the request.

- `mode` (enum, required)
  - Allowed values: `off`, `alert`, `block`
- `action` (string, optional, nullable) — `observe` or `block`.
- `blocked_reason` (string, optional, nullable)
- `would_block` (boolean, optional, default: false) — The block rule was satisfied; in alert mode this is what a block-mode org would have done.
- `tainted` (boolean, optional, default: false) — Untrusted content (tool results, retrieved documents, web search) was present.
- `taint_sources` (list of string, optional) — `client_tool_result`, `web_search`, `fusion_candidate`.
- `tier2a_score` (double, optional, nullable) — Heuristic detector confidence.
- `tier2b_score` (double, optional, nullable) — Embedding similarity to known attacks.
- `fired_signals` (list of string, optional)
- `structural_violation` (boolean, optional, default: false) — A model-emitted tool call carried an exfiltration-shaped argument.
- `flagged_tools` (list of string, optional)

### PIOutputMetadata

Output-side credential-leak scan of the response text (non-streaming only).

- `credential_findings` (integer, optional, default: 0)
- `redacted` (boolean, optional, default: false)

## Examples

### Basic text response

**Request**

```json
{
  "input": [
    {
      "type": "message",
      "content": "What is the capital of France?",
      "role": "user"
    }
  ],
  "model": "openai/gpt-5.1"
}
```

**Response**

```json
{
  "id": "resp_a1b2c3d4e5f6",
  "created_at": "2026-03-23T12:00:00Z",
  "model": "openai/gpt-5.1",
  "output": [
    {
      "id": "msg_001",
      "content": [
        {
          "type": "text",
          "text": "The capital of France is Paris. It is the largest city in France and serves as the country's political, economic, and cultural center."
        }
      ],
      "type": "message",
      "role": "assistant",
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "input_tokens": 14,
    "output_tokens": 28,
    "total_tokens": 42,
    "cost": 0.000049
  },
  "object": "response",
  "vendor": "openai",
  "provider_request_id": "chatcmpl-abc123"
}
```

**SDK Code**

```python Basic text response
import requests

url = "https://api-gateway.merge.dev/v1/responses"

payload = {
    "input": [
        {
            "type": "message",
            "content": "What is the capital of France?",
            "role": "user"
        }
    ],
    "model": "openai/gpt-5.1"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Basic text response
const url = 'https://api-gateway.merge.dev/v1/responses';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"input":[{"type":"message","content":"What is the capital of France?","role":"user"}],"model":"openai/gpt-5.1"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Basic text response
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api-gateway.merge.dev/v1/responses"

	payload := strings.NewReader("{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"What is the capital of France?\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Basic text response
require 'uri'
require 'net/http'

url = URI("https://api-gateway.merge.dev/v1/responses")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"What is the capital of France?\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\"\n}"

response = http.request(request)
puts response.read_body
```

```java Basic text response
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api-gateway.merge.dev/v1/responses")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"What is the capital of France?\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\"\n}")
  .asString();
```

```php Basic text response
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api-gateway.merge.dev/v1/responses', [
  'body' => '{
  "input": [
    {
      "type": "message",
      "content": "What is the capital of France?",
      "role": "user"
    }
  ],
  "model": "openai/gpt-5.1"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Basic text response
using RestSharp;

var client = new RestClient("https://api-gateway.merge.dev/v1/responses");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"What is the capital of France?\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Basic text response
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "input": [
    [
      "type": "message",
      "content": "What is the capital of France?",
      "role": "user"
    ]
  ],
  "model": "openai/gpt-5.1"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api-gateway.merge.dev/v1/responses")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Tool calling

**Request**

```json
{
  "input": [
    {
      "type": "message",
      "content": "What's the weather in San Francisco?",
      "role": "user"
    }
  ],
  "model": "anthropic/claude-sonnet-4-6",
  "tools": [
    {
      "description": "Get the current weather for a location.",
      "name": "get_weather",
      "parameters": {
        "properties": {
          "location": {
            "description": "City name",
            "type": "string"
          }
        },
        "required": [
          "location"
        ],
        "type": "object"
      },
      "type": "function"
    }
  ],
  "tool_choice": "auto"
}
```

**Response**

```json
{
  "id": "resp_d4e5f6a7b8c9",
  "created_at": "2026-03-23T12:01:00Z",
  "model": "anthropic/claude-sonnet-4-6",
  "output": [
    {
      "id": "msg_002",
      "content": [
        {
          "type": "tool_use",
          "id": "call_abc123",
          "input": {
            "location": "San Francisco"
          },
          "name": "get_weather"
        }
      ],
      "type": "message",
      "role": "assistant",
      "finish_reason": "tool_use"
    }
  ],
  "usage": {
    "input_tokens": 85,
    "output_tokens": 32,
    "total_tokens": 117,
    "cost": 0.000735
  },
  "object": "response",
  "vendor": "anthropic",
  "provider_request_id": "msg_01XFDUDYJgAACzvnptvVoYEL"
}
```

**SDK Code**

```python Tool calling
import requests

url = "https://api-gateway.merge.dev/v1/responses"

payload = {
    "input": [
        {
            "type": "message",
            "content": "What's the weather in San Francisco?",
            "role": "user"
        }
    ],
    "model": "anthropic/claude-sonnet-4-6",
    "tools": [
        {
            "description": "Get the current weather for a location.",
            "name": "get_weather",
            "parameters": {
                "properties": { "location": {
                        "description": "City name",
                        "type": "string"
                    } },
                "required": ["location"],
                "type": "object"
            },
            "type": "function"
        }
    ],
    "tool_choice": "auto"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Tool calling
const url = 'https://api-gateway.merge.dev/v1/responses';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"input":[{"type":"message","content":"What\'s the weather in San Francisco?","role":"user"}],"model":"anthropic/claude-sonnet-4-6","tools":[{"description":"Get the current weather for a location.","name":"get_weather","parameters":{"properties":{"location":{"description":"City name","type":"string"}},"required":["location"],"type":"object"},"type":"function"}],"tool_choice":"auto"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Tool calling
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api-gateway.merge.dev/v1/responses"

	payload := strings.NewReader("{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"What's the weather in San Francisco?\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"anthropic/claude-sonnet-4-6\",\n  \"tools\": [\n    {\n      \"description\": \"Get the current weather for a location.\",\n      \"name\": \"get_weather\",\n      \"parameters\": {\n        \"properties\": {\n          \"location\": {\n            \"description\": \"City name\",\n            \"type\": \"string\"\n          }\n        },\n        \"required\": [\n          \"location\"\n        ],\n        \"type\": \"object\"\n      },\n      \"type\": \"function\"\n    }\n  ],\n  \"tool_choice\": \"auto\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Tool calling
require 'uri'
require 'net/http'

url = URI("https://api-gateway.merge.dev/v1/responses")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"What's the weather in San Francisco?\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"anthropic/claude-sonnet-4-6\",\n  \"tools\": [\n    {\n      \"description\": \"Get the current weather for a location.\",\n      \"name\": \"get_weather\",\n      \"parameters\": {\n        \"properties\": {\n          \"location\": {\n            \"description\": \"City name\",\n            \"type\": \"string\"\n          }\n        },\n        \"required\": [\n          \"location\"\n        ],\n        \"type\": \"object\"\n      },\n      \"type\": \"function\"\n    }\n  ],\n  \"tool_choice\": \"auto\"\n}"

response = http.request(request)
puts response.read_body
```

```java Tool calling
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api-gateway.merge.dev/v1/responses")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"What's the weather in San Francisco?\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"anthropic/claude-sonnet-4-6\",\n  \"tools\": [\n    {\n      \"description\": \"Get the current weather for a location.\",\n      \"name\": \"get_weather\",\n      \"parameters\": {\n        \"properties\": {\n          \"location\": {\n            \"description\": \"City name\",\n            \"type\": \"string\"\n          }\n        },\n        \"required\": [\n          \"location\"\n        ],\n        \"type\": \"object\"\n      },\n      \"type\": \"function\"\n    }\n  ],\n  \"tool_choice\": \"auto\"\n}")
  .asString();
```

```php Tool calling
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api-gateway.merge.dev/v1/responses', [
  'body' => '{
  "input": [
    {
      "type": "message",
      "content": "What\'s the weather in San Francisco?",
      "role": "user"
    }
  ],
  "model": "anthropic/claude-sonnet-4-6",
  "tools": [
    {
      "description": "Get the current weather for a location.",
      "name": "get_weather",
      "parameters": {
        "properties": {
          "location": {
            "description": "City name",
            "type": "string"
          }
        },
        "required": [
          "location"
        ],
        "type": "object"
      },
      "type": "function"
    }
  ],
  "tool_choice": "auto"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Tool calling
using RestSharp;

var client = new RestClient("https://api-gateway.merge.dev/v1/responses");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"What's the weather in San Francisco?\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"anthropic/claude-sonnet-4-6\",\n  \"tools\": [\n    {\n      \"description\": \"Get the current weather for a location.\",\n      \"name\": \"get_weather\",\n      \"parameters\": {\n        \"properties\": {\n          \"location\": {\n            \"description\": \"City name\",\n            \"type\": \"string\"\n          }\n        },\n        \"required\": [\n          \"location\"\n        ],\n        \"type\": \"object\"\n      },\n      \"type\": \"function\"\n    }\n  ],\n  \"tool_choice\": \"auto\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Tool calling
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "input": [
    [
      "type": "message",
      "content": "What's the weather in San Francisco?",
      "role": "user"
    ]
  ],
  "model": "anthropic/claude-sonnet-4-6",
  "tools": [
    [
      "description": "Get the current weather for a location.",
      "name": "get_weather",
      "parameters": [
        "properties": ["location": [
            "description": "City name",
            "type": "string"
          ]],
        "required": ["location"],
        "type": "object"
      ],
      "type": "function"
    ]
  ],
  "tool_choice": "auto"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api-gateway.merge.dev/v1/responses")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Structured output (json_schema)

**Request**

```json
{
  "input": [
    {
      "type": "message",
      "content": "Invent a person.",
      "role": "user"
    }
  ],
  "model": "openai/gpt-5.1",
  "response_format": {
    "json_schema": {
      "name": "person",
      "schema": {
        "additionalProperties": false,
        "properties": {
          "age": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "age"
        ],
        "type": "object"
      },
      "strict": true
    },
    "type": "json_schema"
  }
}
```

**Response**

```json
{
  "id": "resp_b2c3d4e5f6a7",
  "created_at": "2026-03-23T12:03:00Z",
  "model": "openai/gpt-5.1",
  "output": [
    {
      "id": "msg_004",
      "content": [
        {
          "type": "text",
          "text": "{\"name\": \"Ada Lovelace\", \"age\": 36}"
        }
      ],
      "type": "message",
      "role": "assistant",
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "input_tokens": 21,
    "output_tokens": 12,
    "total_tokens": 33,
    "cost": 0.000031
  },
  "object": "response",
  "vendor": "openai",
  "provider_request_id": "chatcmpl-ghi789"
}
```

**SDK Code**

```python Structured output (json_schema)
import requests

url = "https://api-gateway.merge.dev/v1/responses"

payload = {
    "input": [
        {
            "type": "message",
            "content": "Invent a person.",
            "role": "user"
        }
    ],
    "model": "openai/gpt-5.1",
    "response_format": {
        "json_schema": {
            "name": "person",
            "schema": {
                "additionalProperties": False,
                "properties": {
                    "age": { "type": "integer" },
                    "name": { "type": "string" }
                },
                "required": ["name", "age"],
                "type": "object"
            },
            "strict": True
        },
        "type": "json_schema"
    }
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Structured output (json_schema)
const url = 'https://api-gateway.merge.dev/v1/responses';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"input":[{"type":"message","content":"Invent a person.","role":"user"}],"model":"openai/gpt-5.1","response_format":{"json_schema":{"name":"person","schema":{"additionalProperties":false,"properties":{"age":{"type":"integer"},"name":{"type":"string"}},"required":["name","age"],"type":"object"},"strict":true},"type":"json_schema"}}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Structured output (json_schema)
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api-gateway.merge.dev/v1/responses"

	payload := strings.NewReader("{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Invent a person.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"response_format\": {\n    \"json_schema\": {\n      \"name\": \"person\",\n      \"schema\": {\n        \"additionalProperties\": false,\n        \"properties\": {\n          \"age\": {\n            \"type\": \"integer\"\n          },\n          \"name\": {\n            \"type\": \"string\"\n          }\n        },\n        \"required\": [\n          \"name\",\n          \"age\"\n        ],\n        \"type\": \"object\"\n      },\n      \"strict\": true\n    },\n    \"type\": \"json_schema\"\n  }\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Structured output (json_schema)
require 'uri'
require 'net/http'

url = URI("https://api-gateway.merge.dev/v1/responses")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Invent a person.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"response_format\": {\n    \"json_schema\": {\n      \"name\": \"person\",\n      \"schema\": {\n        \"additionalProperties\": false,\n        \"properties\": {\n          \"age\": {\n            \"type\": \"integer\"\n          },\n          \"name\": {\n            \"type\": \"string\"\n          }\n        },\n        \"required\": [\n          \"name\",\n          \"age\"\n        ],\n        \"type\": \"object\"\n      },\n      \"strict\": true\n    },\n    \"type\": \"json_schema\"\n  }\n}"

response = http.request(request)
puts response.read_body
```

```java Structured output (json_schema)
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api-gateway.merge.dev/v1/responses")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Invent a person.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"response_format\": {\n    \"json_schema\": {\n      \"name\": \"person\",\n      \"schema\": {\n        \"additionalProperties\": false,\n        \"properties\": {\n          \"age\": {\n            \"type\": \"integer\"\n          },\n          \"name\": {\n            \"type\": \"string\"\n          }\n        },\n        \"required\": [\n          \"name\",\n          \"age\"\n        ],\n        \"type\": \"object\"\n      },\n      \"strict\": true\n    },\n    \"type\": \"json_schema\"\n  }\n}")
  .asString();
```

```php Structured output (json_schema)
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api-gateway.merge.dev/v1/responses', [
  'body' => '{
  "input": [
    {
      "type": "message",
      "content": "Invent a person.",
      "role": "user"
    }
  ],
  "model": "openai/gpt-5.1",
  "response_format": {
    "json_schema": {
      "name": "person",
      "schema": {
        "additionalProperties": false,
        "properties": {
          "age": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "name",
          "age"
        ],
        "type": "object"
      },
      "strict": true
    },
    "type": "json_schema"
  }
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Structured output (json_schema)
using RestSharp;

var client = new RestClient("https://api-gateway.merge.dev/v1/responses");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Invent a person.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"response_format\": {\n    \"json_schema\": {\n      \"name\": \"person\",\n      \"schema\": {\n        \"additionalProperties\": false,\n        \"properties\": {\n          \"age\": {\n            \"type\": \"integer\"\n          },\n          \"name\": {\n            \"type\": \"string\"\n          }\n        },\n        \"required\": [\n          \"name\",\n          \"age\"\n        ],\n        \"type\": \"object\"\n      },\n      \"strict\": true\n    },\n    \"type\": \"json_schema\"\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Structured output (json_schema)
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "input": [
    [
      "type": "message",
      "content": "Invent a person.",
      "role": "user"
    ]
  ],
  "model": "openai/gpt-5.1",
  "response_format": [
    "json_schema": [
      "name": "person",
      "schema": [
        "additionalProperties": false,
        "properties": [
          "age": ["type": "integer"],
          "name": ["type": "string"]
        ],
        "required": ["name", "age"],
        "type": "object"
      ],
      "strict": true
    ],
    "type": "json_schema"
  ]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api-gateway.merge.dev/v1/responses")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### With routing metadata

**Request**

```json
{
  "input": [
    {
      "type": "message",
      "content": "Explain quantum computing briefly.",
      "role": "user"
    }
  ],
  "model": "openai/gpt-5.1",
  "include_routing_metadata": true
}
```

**Response**

```json
{
  "id": "resp_x7y8z9a1b2c3",
  "created_at": "2026-03-23T12:02:00Z",
  "model": "openai/gpt-5.1",
  "output": [
    {
      "id": "msg_003",
      "content": [
        {
          "type": "text",
          "text": "Quantum computing uses quantum bits (qubits) that can exist in superposition — representing both 0 and 1 simultaneously. This allows quantum computers to explore many solutions in parallel, making them potentially much faster than classical computers for specific problems like cryptography, optimization, and molecular simulation."
        }
      ],
      "type": "message",
      "role": "assistant",
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "input_tokens": 12,
    "output_tokens": 52,
    "total_tokens": 64,
    "cost": 0.000087
  },
  "object": "response",
  "vendor": "openai",
  "provider_request_id": "chatcmpl-def456",
  "routing": {
    "policy_id": "policy_abc123def456",
    "policy_name": "Production Policy",
    "strategy": "cost_optimized",
    "intelligent_routing_used": true,
    "complexity_score": 0.35,
    "adjusted_score": 0.12,
    "selected_tier": 0,
    "total_tiers": 2,
    "routing_reason": "Simple prompt routed to cost-effective tier",
    "model_requested": null,
    "model_used": "openai/gpt-5.1",
    "credential_type": "managed",
    "cost_usd": 0.000087,
    "merge_fee_usd": 0.00000435,
    "latency": {
      "policy_lookup_ms": 0.5,
      "routing_decision_ms": 3.2,
      "llm_call_ms": 450.1,
      "total_ms": 453.8
    }
  }
}
```

**SDK Code**

```python With routing metadata
import requests

url = "https://api-gateway.merge.dev/v1/responses"

payload = {
    "input": [
        {
            "type": "message",
            "content": "Explain quantum computing briefly.",
            "role": "user"
        }
    ],
    "model": "openai/gpt-5.1",
    "include_routing_metadata": True
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript With routing metadata
const url = 'https://api-gateway.merge.dev/v1/responses';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"input":[{"type":"message","content":"Explain quantum computing briefly.","role":"user"}],"model":"openai/gpt-5.1","include_routing_metadata":true}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go With routing metadata
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api-gateway.merge.dev/v1/responses"

	payload := strings.NewReader("{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Explain quantum computing briefly.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"include_routing_metadata\": true\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby With routing metadata
require 'uri'
require 'net/http'

url = URI("https://api-gateway.merge.dev/v1/responses")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Explain quantum computing briefly.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"include_routing_metadata\": true\n}"

response = http.request(request)
puts response.read_body
```

```java With routing metadata
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api-gateway.merge.dev/v1/responses")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Explain quantum computing briefly.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"include_routing_metadata\": true\n}")
  .asString();
```

```php With routing metadata
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api-gateway.merge.dev/v1/responses', [
  'body' => '{
  "input": [
    {
      "type": "message",
      "content": "Explain quantum computing briefly.",
      "role": "user"
    }
  ],
  "model": "openai/gpt-5.1",
  "include_routing_metadata": true
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp With routing metadata
using RestSharp;

var client = new RestClient("https://api-gateway.merge.dev/v1/responses");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Explain quantum computing briefly.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"include_routing_metadata\": true\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift With routing metadata
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "input": [
    [
      "type": "message",
      "content": "Explain quantum computing briefly.",
      "role": "user"
    ]
  ],
  "model": "openai/gpt-5.1",
  "include_routing_metadata": true
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api-gateway.merge.dev/v1/responses")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### With guardrails metadata

**Request**

```json
{
  "input": [
    {
      "type": "message",
      "content": "Summarize the attached support ticket.",
      "role": "user"
    }
  ],
  "model": "openai/gpt-5.1",
  "include_guardrails_metadata": true
}
```

**Response**

```json
{
  "id": "resp_g4u5a6r7d8r9",
  "created_at": "2026-09-14T09:41:00Z",
  "model": "openai/gpt-5.1",
  "output": [
    {
      "id": "msg_004",
      "content": [
        {
          "type": "text",
          "text": "The customer cannot sign in after a password reset and asks for the reset link to be re-sent to their email on file."
        }
      ],
      "type": "message",
      "role": "assistant",
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "input_tokens": 148,
    "output_tokens": 31,
    "total_tokens": 179,
    "cost": 0.000062
  },
  "object": "response",
  "vendor": "openai",
  "provider_request_id": "chatcmpl-ghi789",
  "guardrails": {
    "prompt_injection": {
      "mode": "alert",
      "action": "observe",
      "blocked_reason": null,
      "skipped_reason": null,
      "score": 0.12,
      "block_threshold": 0.57,
      "model_version": "protectai-deberta-v3-v2",
      "triggering_segment": {
        "id": "msg_1",
        "kind": "user_message",
        "score": 0.12
      },
      "segments": [
        {
          "id": "sys_0",
          "kind": "system_message",
          "trusted": true,
          "score": 0.01,
          "lexical_hit": false
        },
        {
          "id": "msg_1",
          "kind": "user_message",
          "trusted": true,
          "score": 0.12,
          "lexical_hit": false
        }
      ],
      "allowlist_skipped_segment_ids": [],
      "indirect": {
        "mode": "off",
        "action": null,
        "blocked_reason": null,
        "would_block": false,
        "tainted": false,
        "taint_sources": [],
        "tier2a_score": null,
        "tier2b_score": null,
        "fired_signals": [],
        "structural_violation": false,
        "flagged_tools": []
      },
      "output": {
        "credential_findings": 0,
        "redacted": false
      },
      "policy_scope": "org",
      "latency_ms": 214.7
    },
    "dlp": {
      "status": "redacted",
      "action": "redact",
      "skipped_reason": null,
      "finding_count": 1,
      "entity_counts": {
        "EMAIL_ADDRESS": 1
      },
      "action_counts": {
        "REDACT": 1
      },
      "rule_ids": [
        "6f1c2a8e-9b3d-4e5f-8a7b-1c2d3e4f5a6b"
      ],
      "policy_scope": "org",
      "latency_ms": 38
    }
  }
}
```

**SDK Code**

```python With guardrails metadata
import requests

url = "https://api-gateway.merge.dev/v1/responses"

payload = {
    "input": [
        {
            "type": "message",
            "content": "Summarize the attached support ticket.",
            "role": "user"
        }
    ],
    "model": "openai/gpt-5.1",
    "include_guardrails_metadata": True
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript With guardrails metadata
const url = 'https://api-gateway.merge.dev/v1/responses';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"input":[{"type":"message","content":"Summarize the attached support ticket.","role":"user"}],"model":"openai/gpt-5.1","include_guardrails_metadata":true}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go With guardrails metadata
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api-gateway.merge.dev/v1/responses"

	payload := strings.NewReader("{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Summarize the attached support ticket.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"include_guardrails_metadata\": true\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby With guardrails metadata
require 'uri'
require 'net/http'

url = URI("https://api-gateway.merge.dev/v1/responses")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Summarize the attached support ticket.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"include_guardrails_metadata\": true\n}"

response = http.request(request)
puts response.read_body
```

```java With guardrails metadata
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api-gateway.merge.dev/v1/responses")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Summarize the attached support ticket.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"include_guardrails_metadata\": true\n}")
  .asString();
```

```php With guardrails metadata
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api-gateway.merge.dev/v1/responses', [
  'body' => '{
  "input": [
    {
      "type": "message",
      "content": "Summarize the attached support ticket.",
      "role": "user"
    }
  ],
  "model": "openai/gpt-5.1",
  "include_guardrails_metadata": true
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp With guardrails metadata
using RestSharp;

var client = new RestClient("https://api-gateway.merge.dev/v1/responses");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"input\": [\n    {\n      \"type\": \"message\",\n      \"content\": \"Summarize the attached support ticket.\",\n      \"role\": \"user\"\n    }\n  ],\n  \"model\": \"openai/gpt-5.1\",\n  \"include_guardrails_metadata\": true\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift With guardrails metadata
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "input": [
    [
      "type": "message",
      "content": "Summarize the attached support ticket.",
      "role": "user"
    ]
  ],
  "model": "openai/gpt-5.1",
  "include_guardrails_metadata": true
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api-gateway.merge.dev/v1/responses")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```