merge-gateway-python
Python SDK for the Merge Gateway API.
Installation
pip install merge-gateway-python
# Local development install
pip install -e ./
Quick start
from merge_gateway import MergeGateway
client = MergeGateway(
api_key="sk-...",
base_url="https://api-gateway-develop.merge.dev/v1", # default
)
Usage
Responses
# Non-streaming
response = client.responses.create(
model="openai/gpt-4o",
input=[{"type": "message", "role": "user", "content": "Tell me a bedtime story about a otter."}],
)
print(response.output[0].content)
# Streaming
stream = client.responses.create(
model="openai/gpt-4o",
input=[{"type": "message", "role": "user", "content": "Hello"}],
stream=True,
)
for event in stream:
print(event)
Models
# List models (with optional pagination)
models = client.models.list()
for m in models.data:
print(m.id, m.display_name)
# Filter by provider
openai_models = client.models.list(provider="openai")
# Retrieve a specific model
model = client.models.retrieve("openai/gpt-4o")
Embeddings
result = client.embeddings.create(
model="openai/text-embedding-3-small",
input="The food was delicious",
encoding_format="float",
)
print(result.data[0].embedding)
Embedded Routing (customers)
Provision each of your end customers as a Customer with its own routing policies, provider keys, and budget, then scope LLM requests to it with the customer field.
# Provision a customer
customer = client.customers.create(name="Acme", origin_id="acme-corp")
client.customers.routing_policies.create(
customer.id,
name="workflow-a",
strategy="PRIORITY",
is_default=True,
priority_order=[
{"model": "openai/gpt-5.5", "priority": 1},
{"model": "anthropic/claude-opus-4-8", "priority": 2},
],
)
client.customers.keys.upsert(customer.id, vendor="openai", api_key="sk-...")
client.customers.budgets.create(
customer.id, spending_limit=50, reset_period="MONTHLY", spending_limit_type="HARD"
)
# Scope a request to the customer (omit `model` to route via its default policy)
response = client.responses.create(input="Hello!", customer=customer.id)
# Per-customer spend report
usage = client.customers.usage(customer.id, start="2026-07-01", end="2026-07-31")
print(usage.customer_byok_spend, usage.organization_byok_spend, usage.merge_spend)
Structured output
Request schema-constrained JSON with response_format. strict is
tri-state: omit it for the provider default, pass strict=False for schemas
with optional fields or unions (OpenAI-style strict mode rejects those). If
the routed model can't honor the schema, the gateway returns a clear
400 unsupported_params — never silent best-effort JSON.
from typing import Optional
from pydantic import BaseModel
from merge_gateway import response_format_from_model
class Person(BaseModel):
name: str
age: Optional[int] = None
response = client.responses.create(
model="openai/gpt-4o",
input="Invent a person",
response_format=response_format_from_model("person", Person, strict=False),
)
Or hand-build the payload (typed models in merge_gateway.types or a plain dict):
response = client.responses.create(
model="openai/gpt-4o",
input="Invent a person",
response_format={
"type": "json_schema",
"json_schema": {
"name": "person",
"schema": {
"type": "object",
"properties": {"name": {"type": "string"}},
"required": ["name"],
"additionalProperties": False,
},
"strict": True,
},
},
)
Error handling
from merge_gateway import AuthenticationError, RateLimitError
try:
response = client.responses.create(model="openai/gpt-4o", input="Hi")
except AuthenticationError:
print("Check your API key")
except RateLimitError:
print("Slow down!")
Publishing to PyPI
python -m build
twine upload dist/*
Metadata
Release files for merge-gateway-python 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| merge_gateway_python-0.4.0.tar.gz | 28.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| merge_gateway_python-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 54.8 kB
Release files / merge_gateway_python-0.4.0.tar.gz
| Download URL | merge_gateway_python-0.4.0.tar.gz |
|---|---|
| Size | 28.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0b3811f1f97d1aed10dbc20803b0b6643f898a2e19609fd2aab7f04a7b7488d9
|
|
BLAKE2b-256 checksum How to use checksums |
a0067771ad11e333483f2d584d0089a3a2b3eff736623d77cd7053470e8dfb5a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Release files / merge_gateway_python-0.4.0-py3-none-any.whl
| Download URL | merge_gateway_python-0.4.0-py3-none-any.whl |
|---|---|
| Size | 26.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3a5c7c6c4144d10bae93ca65eff23de54cbf1f94d2ed86343f44faa5bd9c4a6c
|
|
BLAKE2b-256 checksum How to use checksums |
d6d0297fda781845167695221754a576eab10e5bad54b2177439d16711c49a15
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.3
|
Security for merge-gateway-python 0.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.