Straits Hub — Enterprise AI Fabric Gateway

OpenAPI 3.1.0/v1/api/v132 operations

One governed interface between every employee, application and agent — and every AI resource the company is authorized to use. OpenAI/OpenRouter-compatible chat, OpenAI Responses and Anthropic Messages protocol skins, plus embeddings, rerank, moderations, audio, realtime session descriptors, images, async video and batch jobs, files/artifacts, model discovery, a full generation audit ledger and generation feedback.

Every generation runs the fabric pipeline: guardrails → exact cache → two-stage routing (hard filters, then a dynamic latency/cost/quality/quota objective) → provider dispatch on trusted egress nodes with error-conditioned fallback → output guardrails → audit. Fabric behavior is documented under x-fabric-* extensions.

Authentication

Every data-plane endpoint (everything except GET /openapi.json) requires a fabric API key: Authorization: Bearer fab_… (an x-api-key header is also accepted). Keys resolve to a principal bound to a project, a default logical profile, budgets and a guardrail policy — so identity, policy and spend are attached before routing ever runs. Invalid or missing keys return 401 authentication_failed.

fab_demo_adminAdmin / platform engineer — default profile @company/general-balanced. Use this key for the samples on this page.
fab_demo_appProduct application principal — default profile @company/general-fast.
fab_demo_agentAutonomous agent principal — default profile @company/auto.
curl
curl https://fabric.whymelabs.com/v1/models \
  -H "Authorization: Bearer fab_demo_admin"

Both route prefixes serve the same handlers: /v1/... and /api/v1/... — point any OpenAI/OpenRouter SDK at either as its base URL.

Streaming (SSE)

Set stream: true on chat-like endpoints to receive Server-Sent Events. The fabric speaks three streaming dialects, matching each protocol skin:

  • /chat/completions — OpenAI style: data: {chat.completion.chunk} frames (role chunk, paced content deltas, delta.tool_calls, then a final usage-bearing chunk), terminated by data: [DONE].
  • /responses — typed response.* events with an event: name and monotonic sequence_number (response.createdresponse.output_item.addedresponse.content_part.addedresponse.output_text.delta… → response.completed). No [DONE] terminator.
  • /messages — Anthropic named events: message_start, ping, content_block_start / content_block_delta (text_delta, input_json_delta) / content_block_stop, message_delta (carries stop_reason + output tokens), message_stop. No [DONE].
curl
curl -N https://fabric.whymelabs.com/v1/chat/completions \
  -H "Authorization: Bearer fab_demo_admin" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "@company/general-fast",
  "stream": true,
  "messages": [{ "role": "user", "content": "Hello fabric" }]
}'
event stream
data: {"id":"gen_…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"role":"assistant","content":""},"logprobs":null,"finish_reason":null}],…}

data: {"id":"gen_…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Hello! "},"logprobs":null,"finish_reason":null}],…}

data: {"id":"gen_…","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"logprobs":null,"finish_reason":"stop"}],"usage":{…}}

data: [DONE]

Guardrails still apply to streams: the pipeline runs output guardrails before frames are emitted, so a blocked generation fails with a 403 error instead of a truncated stream. When metadata is requested, fabric_metadata rides on the final usage-bearing chunk (OpenAI dialect) or the completed response object.

Error taxonomy

Every failure — gateway, guardrail, quota, or any provider's native error — is normalized into one canonical class (memo §9.1). The class is carried in error.code, so clients can branch on stable semantics instead of provider-specific strings. Classes marked retryable are retried internally on an alternate credential / node / endpoint before the gateway ever returns the error; safety blocks (content_policy_rejection, dlp_block) are never retried on a more permissive route.

error wire shape (all endpoints except /messages)
{
  "error": {
    "message": "secrets detected in prompt: AWS access key",
    "type": "content_policy_violation",
    "code": "dlp_block",
    "param": null
  }
}

POST /messages uses the Anthropic envelope instead: { "type": "error", "error": { "type", "message" } }.

classstatusretryablemeaning
authentication_failed401yesAPI key or provider credential rejected. Internally the fabric quarantines the credential and retries an alternate; at the edge it is a 401.
credential_expired401yesProvider credential expired; refreshed or replaced where authorized.
rate_limited429yesProvider or gateway rate limit. Fallback tries alternate account/deployment/contract, same model first.
quota_exhausted429yesA quota pool is exhausted; alternate account or contract may be tried.
egress_unavailable502yesNo healthy egress node for the required trust tier/region.
provider_overloaded503yesProvider returned an overload signal; alternate endpoint/provider for the same canonical model.
provider_unavailable503yesProvider endpoint down or unreachable.
network_timeout504yesAttempt exceeded its deadline; one bounded retry if the request deadline permits.
unsupported_parameter400noA parameter the selected endpoint cannot honor exactly.
unsupported_modality400noThe operation/modality is not supported by any allowed endpoint.
context_too_long400noInput exceeds the model context window. Moving to a larger-context model is a routing decision, never a silent retry.
invalid_structured_output502yesModel output failed schema validation; repair retry, then a schema-compatible model.
content_policy_rejection403noGuardrail content block. NEVER retried on a more permissive model.
dlp_block403noData-loss-prevention block (secrets/PII egress). Never retryable.
tool_execution_failed502noA tool call failed; retry policy respects tool idempotency declarations.
invalid_request400noMalformed request (bad JSON, missing fields, unknown enum values). Also used with status 404 for unknown resource ids.
budget_exceeded402noThe request would exceed a hard budget ceiling.
internal500noUnexpected fabric-internal failure.

Logical profiles

Applications should target organization-managed logical service profiles rather than volatile provider model names (memo §4.3). A profile encapsulates an approved model set, routing objective, guardrail policy, cache policy, cost ceiling, resilience profile and audit mode — so operators can move traffic between models without a single client change. Pass a profile id anywhere a model is accepted; profiles also appear in GET /models as type: "profile" entries.

@company/general-fastLow-latency default for interactive product surfaces.
@company/general-balancedBalanced quality/cost for most internal workloads.
@company/general-bestMaximum quality for hard reasoning and drafting.
@company/code-productionProduction code generation and review; ZDR enforced.
@company/confidentialRestricted data: SG region, Tier A/B egress, ZDR, strict DLP.
@company/visionImage understanding and document vision.
@company/embeddingsDeterministic embeddings; never silently changes model or dimensions.
@company/voiceSpeech synthesis and transcription.
@company/imageMarketing and product image generation.
@company/videoAsync video generation jobs.
@company/autoFabric auto-routing across the full approved set.
fabric/autoAlias of @company/auto for OpenRouter-style clients.

OpenRouter-compatible fields (model, models, provider, session_id) stay valid; enterprise controls live in the optional routing object. session_id keeps model pinning and prompt-cache affinity stable across an agent session. routing.explain: true (or X-Fabric-Explain: true) attaches the full fabric_metadata route explanation; X-OpenRouter-Metadata: enabled attaches it with node refs masked.

request with fabric extensions
{
  "model": "@company/confidential",
  "session_id": "agent-session-01HXYZ",
  "messages": [{ "role": "user", "content": "Review this contract." }],
  "provider": { "zdr": true },
  "routing": {
    "deadline_ms": 15000,
    "maximum_cost_usd": 0.20,
    "explain": true
  }
}

Chat

OpenAI/OpenRouter-compatible chat completions.

Responses

OpenAI Responses protocol skin.

Messages

Anthropic Messages protocol skin.

Embeddings

Pinned-model embeddings — never a silent vector-space change.

Rerank

Query/document relevance scoring.

Moderations

Policy classification driven by the fabric's own guardrail evaluators.

Audio

Speech synthesis and transcription.

Realtime

Realtime session descriptors — routed once, pinned for the session.

Images

Synchronous image generation.

Video

Asynchronous video jobs with polling and cancellation.

Batch

Durable asynchronous batch processing.

Files & Artifacts

Metadata-only registration; bytes go direct to storage.

Models

Canonical models and logical service profiles.

Generations

Usage, attempts and route-explanation audit surface.

Feedback

Runtime quality signal on ledgered generations.

Meta

API description.