You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Failure Action Contracts for OpenAI-Compatible SDKs (September 2026)
#85
Most OpenAI-compatible SDK examples treat failures as transport events: catch the exception, print the message, maybe retry if the status code looks temporary. That is fine for a quickstart. It is not enough for a production gateway route where authentication, quota, route policy, burst limits, upstream instability, and pricing evidence all affect the next correct action.
I think SDKs should expose a small "failure action contract" beside the normal exception object.
The contract would not replace HTTP status codes. It would give the application a stable decision field:
Failure class
Typical signal
SDK action
Authentication
401
fix_key
Exhausted quota
402, or 403 with a bounded quota code
fund_account
Route policy
403 without quota semantics
choose_route
Burst limit
429
retry_later
Upstream timeout
408, 502, 503, 504
retry_if_idempotent
Unknown contract break
validation mismatch or unclassified error
inspect_fixture
The important boundary is that not every 403 means "add money", and not every failure should enter a retry loop. A quota failure should stop before retrying. A route-policy failure should show the selected model and account rule, not a billing CTA. A 429 can retry, but only inside a visible attempt budget.
Before posting this on September 11, 2026, I rechecked AIWave's public pricing and status surfaces. https://aiwave.live/api/pricing returned success=true, 64 route records, pricing version a42d372ccf0b5dd13ecf71203521f9d2, group_ratio values of default=3 and vip=1, and OpenAI endpoint metadata for POST /v1/chat/completions. https://aiwave.live/api/v1/pricing returned HTTP 200 with checked=2026-09-10, updated_at=2026-09-10, currency USD, unit per_1m_text_tokens, pricing version 8c7a0c0b30661ccbc13d142cb54d1e4ae445fe774b2c6fa501080db97c7a3e56, and 64 model rows.
Selected public rows from that snapshot:
Model ID
Input / 1M
Cache-hit input / 1M
Output / 1M
Effective date
deepseek-flash
$0.70
$0.0233
$2.10
2026-09-10
deepseek-v3.2
$0.154
null
$0.308
2026-08-27
deepseek-v4-pro
$1.914
$0.0637362
$5.742
2026-08-27
moonshot-v1-128k
$1.80
null
$4.50
2026-08-27
qwen3-max
$1.5621977891
null
$6.2487911565
2026-08-27
Those are public base rows, not final invoices. The applied account group, cache behavior, resolved route, output length, retries, and private receipt still determine the completed charge. That distinction is exactly why the failure action should carry pricing metadata without exposing private billing records.
Here is the fixture shape I would want SDKs to emit in tests and examples:
The SDK test should assert two things. First, a known quota fixture maps to fund_account and never retries. Second, a generic 403 fixture does not map to funding unless the machine-readable code is explicitly a quota code. That one distinction prevents a surprising number of support mistakes.
For gateway maintainers, the public/private split matters. Public evidence can include source URL, checked date, pricing version, unit, currency, model ID, and base rates. Private receipts can include applied group, exact resolved route, request ID, and observed usage. The SDK should join those concepts carefully, not merge them into one blob.
Discussion question: should SDKs standardize a small action_class vocabulary for OpenAI-compatible gateways, or should each gateway publish its own mapping table? My bias is a shared vocabulary with gateway-specific extensions, because application code should not need a separate retry and billing branch for every provider-shaped endpoint.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Most OpenAI-compatible SDK examples treat failures as transport events: catch the exception, print the message, maybe retry if the status code looks temporary. That is fine for a quickstart. It is not enough for a production gateway route where authentication, quota, route policy, burst limits, upstream instability, and pricing evidence all affect the next correct action.
I think SDKs should expose a small "failure action contract" beside the normal exception object.
The contract would not replace HTTP status codes. It would give the application a stable decision field:
401fix_key402, or403with a bounded quota codefund_account403without quota semanticschoose_route429retry_later408,502,503,504retry_if_idempotentinspect_fixtureThe important boundary is that not every
403means "add money", and not every failure should enter a retry loop. A quota failure should stop before retrying. A route-policy failure should show the selected model and account rule, not a billing CTA. A429can retry, but only inside a visible attempt budget.Before posting this on September 11, 2026, I rechecked AIWave's public pricing and status surfaces.
https://aiwave.live/api/pricingreturnedsuccess=true, 64 route records, pricing versiona42d372ccf0b5dd13ecf71203521f9d2,group_ratiovalues ofdefault=3andvip=1, and OpenAI endpoint metadata forPOST /v1/chat/completions.https://aiwave.live/api/v1/pricingreturned HTTP 200 withchecked=2026-09-10,updated_at=2026-09-10, currencyUSD, unitper_1m_text_tokens, pricing version8c7a0c0b30661ccbc13d142cb54d1e4ae445fe774b2c6fa501080db97c7a3e56, and 64 model rows.Selected public rows from that snapshot:
deepseek-flash$0.70$0.0233$2.10deepseek-v3.2$0.154null$0.308deepseek-v4-pro$1.914$0.0637362$5.742moonshot-v1-128k$1.80null$4.50qwen3-max$1.5621977891null$6.2487911565Those are public base rows, not final invoices. The applied account group, cache behavior, resolved route, output length, retries, and private receipt still determine the completed charge. That distinction is exactly why the failure action should carry pricing metadata without exposing private billing records.
Here is the fixture shape I would want SDKs to emit in tests and examples:
{ "fixture_type": "failure_action_contract", "base_url": "https://aiwave.live/v1", "model": "deepseek-v4-pro", "status": 403, "error_code": "insufficient_user_quota", "action_class": "fund_account", "retryable": false, "pricing_snapshot": { "source": "https://aiwave.live/api/v1/pricing", "checked": "2026-09-10", "version": "8c7a0c0b30661ccbc13d142cb54d1e4ae445fe774b2c6fa501080db97c7a3e56", "unit": "per_1m_text_tokens", "currency": "USD" }, "redaction": { "api_key": "excluded", "prompt": "excluded", "completion": "excluded", "account_identifier": "excluded" } }The SDK test should assert two things. First, a known quota fixture maps to
fund_accountand never retries. Second, a generic403fixture does not map to funding unless the machine-readable code is explicitly a quota code. That one distinction prevents a surprising number of support mistakes.For gateway maintainers, the public/private split matters. Public evidence can include source URL, checked date, pricing version, unit, currency, model ID, and base rates. Private receipts can include applied group, exact resolved route, request ID, and observed usage. The SDK should join those concepts carefully, not merge them into one blob.
Discussion question: should SDKs standardize a small
action_classvocabulary for OpenAI-compatible gateways, or should each gateway publish its own mapping table? My bias is a shared vocabulary with gateway-specific extensions, because application code should not need a separate retry and billing branch for every provider-shaped endpoint.All reactions