Skip to content
Niu DocsNiu 牛元文档
Dashboard控制台

API integration

Start with the API quickstart for HTTP requests or the SDK quickstart for typed JavaScript calls and streaming.

The REST specification is generated from the complete OpenAPI contract. The SDK reference is generated from public TypeScript declarations. Download the bundled OpenAPI JSON for tools that consume the specification. Interface changes are checked against generated output in CI.

Management automation uses the authority required by the specific operation; a customer workspace key is not a platform administrator credential. Read administrator access and security for setup, sign-in, session restoration and revocation. Exact authentication and session schemas are in the REST reference.

Request logs describe usage and timing recorded for requests handled by Niu. Optional client correlation metadata does not turn these records into an external agent execution trace. Niu does not own task orchestration, external tool logs or outcome evaluation.

Task Start here
Send an application request API tutorial or SDK tutorial
Check a field, response or authentication requirement Generated REST specification
Find a typed client method Generated SDK reference
Restore Chat or Video work Generations
Understand a saved request or charge Request logs and Usage and billing

Administration explains Provider setup, customer tariffs, payment integration and branding. The NiuAdminClient reference contains the generated client interfaces; guides do not duplicate their signatures.

The JavaScript SDK exposes admin.getChatDraft() and admin.saveChatDraft(). Read the current revision before saving or clearing; a conflict requires an explicit reload and reconciliation. Saving a draft does not submit a model request.

The customer billing contract, included by the main OpenAPI document, covers workspace-authorized billing summaries and invoice line reads. Customer charges use explicit selling tariffs, independent from Provider prices. Unpriced requests are not assumed free; unresolved charges remain unknown. Monetary amounts and aggregate counts are exact decimal integer strings. Workspace billing tariff lists and model-discovery customer prices include every matching saved tariff; they do not silently stop at 1,000 entries. These compatibility responses remain unpaginated, with memory use proportional to their size.

Invoice text lines retain the tariff revision and selected context threshold used by the charge, rather than substituting current model prices. A revision can produce multiple lines for different context thresholds; clients must preserve those distinct groups. Absent cache-read, cache-write and reasoning quantities remain unknown. A null category rate means that category is not configured in the bound tariff; an omitted rate is unknown. A null selected context threshold selects the base tariff and must not be displayed as a zero threshold. Use exact integer strings when displaying or reconciling amounts.

Tariff publication, invoice creation and confirmed external-payment recording require installation authority. Invoice intervals use UTC dispatch timestamps with an inclusive from_ms and exclusive to_ms, bounded to 366 days. Preserve the caller’s idempotency key when replaying the same invoice request. Overlapping periods, unresolved priced requests and changed replay parameters produce conflicts; clients must not retry these by inventing a new key.

The JavaScript SDK provides getCustomerBilling, publishCustomerTariff, issueCustomerInvoice, getCustomerInvoiceLines, and recordCustomerInvoicePayment. Its packaged inspect-billing.mjs example reads the latest 100 invoices and reconciles line totals using exact integer arithmetic. Invoice creation does not send an invoice or collect money, and payment recording only records an already confirmed external payment. Keep administration credentials server-side and internal invoice/rate identifiers out of product displays.

Already incurred text charges retain their full reported amount even if they exceed the original reservation or approved company credit. Balance and available capacity can therefore be negative. New paid requests require sufficient available capacity and can return HTTP 402 budget_exceeded; billing reads remain available. A balance refund is a separate ledger entry and does not erase the original charge. The charge-reconciliation API compares gross original charges with their original balance debits; it does not subtract refunds. Use the balance ledger for net funds. Actual nonempty reconciliation and refund verification records the current text-accounting boundary. Preserve the refund idempotency key when replaying the same administrative action.

An actual credit-backed run verified overrun settlement, refusal across restart, an idempotent internal refund and a subsequent real model completion. This does not establish bank refund or customer-funded video behavior. See the actual company-credit evidence.

An authorized personal upstream route is funded by its credential owner. It does not reserve or debit Niu customer funds or platform procurement budgets. A saved workspace procurement budget therefore does not by itself prevent an authorized personal Chat or video call. Current key/model permissions, Guardrails and request-rate controls still apply. Shared priced routes retain procurement admission checks; this distinction does not grant access to another company’s personal credential. Personal and customer-priced operations retain an immutable funding source across their attempt bindings; candidate selection cannot switch between them. Chat pools support one bounded successor after a qualified immediate OpenRouter authentication rejection; uncertain execution is never retried. Personal text requests prepare their operation, route and admission bindings atomically before the separate dispatch permission check. A failed preparation does not leave a partially bound request. This does not enable automatic retries after uncertain dispatch.

Shared video routes retain the legacy procurement-budget restriction; personal video routes do not reserve or debit that budget. Personal video still enforces key RPM/concurrency controls. A finite key token-rate budget rejects video with 422 key_token_bound_required when the channel lacks a supported token admission bound.

Key spending limits apply to new customer-liability reservations. Read committed_nanos and remaining_nanos from the spending-limit API; preserve these exact decimal integer strings rather than converting them to floating-point money. Remaining allowance is clamped to zero when actual consumption exceeds the cap. A cap does not truncate an already incurred charge or cancel upstream work. Secret rotation retains the same spending identity and committed amount.

An actual streamed text request exceeded its requested output bound: the original 1,000-nano reservation was released, the full 11,000-nano customer charge was posted, and the rotated key showed zero remaining allowance and rejected further requests before and after restart. This is a scoped text-accounting observation, not qualification of media overruns or every provider. See the verification details.

Platform administrators can discover saved pools through GET /api/v1/pools/index, or the SDK’s listModelRoutePools method. Pass limit (1–100, default 50), then use the returned next_after as after for the next page. The list includes enabled and disabled configurations. Its live alias-based traversal is not a snapshot; refresh from the first page to see new aliases inserted before the current cursor. Existing alias lookup and revision-history endpoints retain their response formats.

Inference model discovery traverses all saved route-pool pages rather than silently limiting discovery to the first 1,000 pools. Disabled and unauthorized pools remain excluded. The compatibility /v1/models response remains a complete list; bounded database fetches do not imply a fixed-size response. Inference discovery reads shared mappings, personal ownership, Provider eligibility, cooldowns and every pool page in one read-only database snapshot. It composes the catalog without per-pool route queries or credential decryption. Static aliases remain shadowed by database aliases, including disabled and foreign personal mappings. This is a per-read catalog snapshot, not a published inference generation; actual request admission still checks current permissions and credential state. Management pagination remains a separate live traversal.

A revisioned pool update applies to selection for new requests. Disabling a candidate does not cancel a generation already dispatched through it. That request retains its original mapping and pool revision for diagnosis and accounting; subsequent requests can select another eligible candidate under the new revision. Customer model aliases and customer tariffs remain separate from Provider mappings.

This behavior has been exercised with actual concurrent priced requests and independent charge/revision checks. Separately, Chat pools can try a different credential after a canonical OpenRouter immediate HTTP 401, once durable nonexecution and released reservations are confirmed. The limit is two submitted attempts under one operation and deadline, preserving customer price and funding source. Other errors and streams already returned to the client are not retried. See the route pool contract and evidence.

The workspace request list and detail endpoints report the customer model alias, execution state, reported usage, customer charge and saved timing. A pool’s selected Provider mapping and confidential procurement prices are not customer billing data. Installation credentials receive the same customer-facing detail shape; they do not expand it with wholesale costs. Request metadata responses use Cache-Control: no-store.

Use the detailed response’s nullable fields as documented in the generated request contracts. Missing timing or usage is unknown, not a measured zero. Workspace scope applies to each request; a foreign request returns 404. Display meaningful model/key names and timestamps rather than the internal identifiers needed for API routing.

GET /catalog/v1/models and the /models/ page list aliases an operator explicitly marks with public_catalog = true. The response contains the alias, declared capabilities, and optional descriptive catalog metadata such as name, context limits and modalities; it omits provider names, upstream identifiers, endpoints, credentials and Provider prices. Catalog visibility does not authorize inference. Applications still use scoped keys with /v1/models and the inference endpoints.

The operator name is an existing administration API contract for a workspace member; the dashboard uses Users. Accounts sign in with their own credentials and receive their assigned role and workspace access. Installation setup credentials are separate from member sessions and application API keys. The password session API is opt-in through NIU_AUTH_PUBLIC_ORIGIN, which must be an HTTPS origin without a path, credentials, query or fragment. Deploy it behind HTTPS at that origin. Self-registration and identity federation remain unimplemented.

PUT /api/v1/operators/{operator}/password lets an installation administrator or a scoped owner provision an existing member with email, password and optional expected_revision. First provision omits the revision; resets require the last returned revision and revoke all prior sessions atomically. Passwords require at least 15 characters and at most 1,024 UTF-8 bytes; spaces and Unicode are preserved. The response contains the new revision, never the hash.

POST /api/v1/auth/login accepts email and password and returns a scoped eight-hour bearer token and session metadata. It grants the member’s existing role and workspace access, never installation access. Wrong passwords and unknown identities return the same HTTP 401 response. Durable admission limits allow five attempts per normalized email and 120 per installation in a 60-second window; limited requests return HTTP 429 with Retry-After: 60. Both routes limit JSON bodies to 4 KiB and mark success/error responses Cache-Control: no-store. A supplied browser Origin must match the configured origin. These routes do not set browser cookies; the dashboard uses the separate browser endpoints below. Without configuration, password login returns HTTP 501. For same-origin browser clients, POST /api/v1/auth/browser/login uses the same credentials and limits, requires the configured HTTPS Origin and sets an eight-hour Secure, HttpOnly, SameSite=Lax host-only cookie. Its JSON contains session metadata without the bearer token. Shared member authorization validates the saved session on every request and requires a matching Origin or browser Sec-Fetch-Site: same-origin metadata; a mismatched Origin always fails. Duplicate Authorization headers are rejected. When supplied, Fetch Metadata must contain exactly one same-origin value even with a matching Origin. Installation tokens are never accepted through this cookie path. POST /api/v1/auth/browser/logout requires the matching Origin, revokes the current session and expires the cookie. Already unusable sessions still clear successfully; storage failures do not claim sign-out or clear the cookie. The dashboard discovers this mode through GET /api/v1/auth/config, signs in with the browser endpoint, and restores the server session without saving a bearer token in browser storage. Real HTTPS browser acceptance remains unfinished.

PUT /api/v1/auth/password lets every signed-in member role change its own password with current_password and password. It accepts no member target or email; installation credentials cannot use it. Current-password checks share sign-in throttling, new passwords follow the same creation policy, and a credential revision change during verification returns HTTP 409 without replacing the newer credential. Success revokes all sessions for that member and returns sign_in_required: true; other members remain unaffected. Browser-cookie requests require the matching Origin and expire the cookie on success. Failed changes preserve sessions. The dashboard provides password changes in account settings; rendered review and HTTPS browser qualification remain open.

GET /api/v1/auth/preferences reads the signed-in member’s saved color mode. PUT /api/v1/auth/preferences accepts {"color_mode":"system"}, "light", or "dark" as the value of color_mode. Every member role can change its own preference; installation tokens and caller-supplied member targets are rejected. The default is system. Preferences are stored in PostgreSQL separately from profile revisions, and browser storage is only a disposable cache. Dashboard and embedded docs controls share this saved preference. Browser-cookie writes use the same Origin checks as profile changes; responses are non-cacheable and request bodies are limited to 1 KiB. Installation-only display choices have no personal account to save to and remain local.

POST /api/v1/auth/logout revokes the member bearer session in the Authorization header. Every member role can sign out; other sessions remain active. Revocation and its audit record are atomic, responses are non-cacheable, and missing, expired or previously revoked credentials return HTTP 401. Installation setup tokens are not member sessions. This API is available even when password login is not configured. The dashboard uses the browser sign-out endpoint for cookie sessions and preserves its session when revocation fails.

The password session contract documents request fields, role restrictions, session responses and failure statuses.

NIU_ADMIN_TOKENS remains the owner-level installation bootstrap credential. An owner can create persistent operators with owner, admin, or viewer roles through POST /api/v1/operators, and issue additional expiring sessions through POST /api/v1/operators/{operator}/sessions. Creation responses contain the bearer token once and include Cache-Control: no-store; list APIs return only identity, role, session IDs, expiry and revocation metadata. Delete an individual session or an operator to revoke access. A revoked or expired token fails the next administrative request.

Operator and session creation/revocation also append immutable, metadata-only audit events in the same database transaction. Events record whether the actor was an installation bootstrap credential or a scoped operator, the actor operator ID when present, target operator/session IDs, tenant scope and timestamp. They never store bearer tokens, token hashes or request bodies. A scoped owner can page through one operator’s events with GET /api/v1/operators/{operator}/events; pages are ordered by timestamp and event ID, limited to 1–100 items, and use next_cursor for stable continuation.

Owners can manage members. Admins can read and write management resources but cannot manage members. Viewers have read access only. Every member has an organization_id and may have a legacy project_id that restricts access to a single workspace. Owners cannot create or manage members outside their own scope. Workspace IDs in dashboard URLs do not grant authority. GET /api/v1/session returns the caller’s current identity, scope, and role permissions without exposing credentials.

The dashboard’s GET /api/v1/workspaces lists workspaces visible to the current administrator, with each workspace’s parent organization. POST /api/v1/workspaces creates one in the requested organization. Organization administrators can create workspaces only inside their organization; installation administrators can select any organization. If an installation has no organization yet, omitting organization_id creates a Personal workspace organization first. API keys, requests, budgets, and usage belong to a workspace; project names remain only in legacy API and storage contracts.

Capabilities are route-specific. Flags in config/niu.toml declare operator-verified behavior; they do not mean Niu has qualified every provider model or endpoint. A request for an unsupported combination is rejected before an attempt is created where the contract below marks it unavailable.

Operation OpenAI-compatible route (provider = "openai" or "openrouter") Native Anthropic route Native Bedrock route
Chat completion, non-streaming Supported; tool and structured-output subsets require separate route flags Basic non-streaming adapter path Basic non-streaming adapter path
Chat completion, streaming Supported; tool deltas need supports_streaming_tool_calls Not implemented Not implemented
Function tools Non-streaming tool-call pass-through with supports_tool_calls; Niu does not execute tools Not implemented Not implemented
Structured JSON output Buffered and streaming json_object / json_schema with supports_structured_output; streaming deltas remain provisional until terminal validation Not implemented Not implemented
Text embeddings Supported only with supports_embeddings; dimensions and base64 output require their own flags Not implemented Not implemented
Responses Buffered and streamed text subset with supports_responses Not implemented Not implemented

The native Anthropic and Bedrock entries describe the current non-streaming chat adapter path, not provider conformance qualification. Tool and structured-output capabilities are deliberately restricted to OpenAI-compatible routes. Pricing applies to bounded text chat, Responses and embeddings; embeddings reserve input capacity only and settle provider-reported prompt usage. Priced Chat supports the documented text-only function-tool conversations; Niu does not execute tools or price hosted tool services. See Model routes for the exact route flags and pricing limits.

Non-streaming provider JSON responses are limited to 16 MiB before decoding. Larger responses fail as an upstream error and remain uncompleted in request activity. Streaming Chat inspects at most 65,536 bytes per Server-Sent Event; interrupted or cancelled streams remain uncertain unless a valid terminal event was observed.

Chat validates common generation parameters before admission or Provider dispatch: temperature from 0 to 2, top_p from 0 to 1, and presence/frequency penalties from -2 to 2. Non-null max_tokens, max_completion_tokens and n must be positive signed 64-bit integers; non-null seed must be a signed 64-bit integer. Only one non-null output token limit may be supplied. stream must be boolean; non-null stream_options must be an object and its include_usage, when present, must be boolean. Invalid values return clear 400 errors without an operation or attempt. Omitted and nullable optional values preserve their existing semantics; Niu does not inject sampling defaults or clamp explicit values. A configured native adapter or priced route may impose stricter supported bounds.

POST /v1/chat/completions accepts OpenAI-compatible function tool definitions, tool_choice, and response_format values json_object or json_schema only when the configured OpenAI-compatible route explicitly enables the corresponding capability. Streaming tool-call deltas require the separate supports_streaming_tool_calls flag. Requests for disabled capabilities return 501 before an operation or attempt is recorded. The unsupported_operation_error message identifies tools, streaming tools or structured JSON and gives a supported alternative. Combined tools plus structured JSON remains unsupported; Niu does not silently remove those requested features. Malformed tool definitions, choices, and schemas receive 400.

Niu forwards tool definitions and structured-output schemas to the provider. It does not execute tools. Non-streaming tool-call responses must reference a declared function and contain JSON-object arguments. Structured-output responses must match the self-contained JSON Schema; json_object responses must be objects. Schema compilation cannot retrieve HTTP or file references and has the documented complexity limits. Provider support must be independently verified by the installation administrator. These features are not enabled on native Anthropic or Bedrock routes. Token-priced routes support text-only function conversations. Structured JSON streams deliver provisional deltas and validate their assembled content before releasing [DONE]; invalid terminal content emits an upstream_invalid_response SSE error without [DONE] and records a failure while reported terminal usage remains accounting evidence. Validation retains at most 1 MiB of content/refusal bytes across 128 choices. A nonempty explicit refusal remains a refusal. Full Responses compatibility, broader protocol conformance, and provider-specific qualification remain release work. See the structured-stream contract and current-input verification for terminal error semantics, accounting and qualification limits.

If a terminal model response fails output validation, Niu returns 502 without delivering the rejected content. Valid, complete and consistent reported input/output token counts still record upstream completion and accrue the pinned customer charge; a failed delivery can therefore have a charge. Missing, invalid, inconsistent or overflowing usage remains unknown and is not replaced with an estimate. HTTP delivery status and upstream execution evidence describe different facts.

Public Chat, Responses, Embeddings and dashboard Chat reject request bodies over 1 MiB (1,048,576 bytes) with HTTP 413 before inference. The same limit applies with or without payload retention, including chunked transfer without a Content-Length header. A request at the byte limit still needs valid JSON, supported fields, authorization and model-specific input bounds. Framework rejections may use plain text rather than the API JSON error envelope.

POST /v1/responses accepts a non-empty string input and optional string instructions, max_output_tokens, temperature, top_p, string-valued metadata, and user. The model route must set supports_responses = true; Niu rewrites the model to the configured upstream name and maps the returned model back to the public alias. The supported output subset includes text messages, reasoning items and refusal content in buffered or streamed responses. Usage maps from Responses input_tokens/output_tokens into durable prompt/completion fields.

Input arrays, images, audio, tools and conversation state are outside this subset. Unsupported fields or malformed shapes return 400; a disabled route capability returns 501 before creating an attempt. Streamed completion requires terminal event and usage evidence; an initial HTTP 200 is not completion. When route pricing is enabled, input plus instructions must fit the configured conservative UTF-8 byte bound and max_output_tokens is reserved before dispatch. See Model routes for current limits. This adapter subset does not imply provider-specific conformance.

POST /v1/embeddings accepts a model alias and one non-empty string or an array of 1–2048 non-empty strings. It optionally accepts dimensions (1–65536), encoding_format (float or base64), and a user string up to 512 bytes. Token-ID arrays, nested inputs, multimodal input, streaming and extra fields are rejected. The configured route must use provider openai or openrouter and explicitly declare embedding support; dimension and base64 support are separate opt-in route declarations. OpenRouter embeddings are not inferred from chat support. A missing declaration or unsupported provider returns 501 before durable operation and attempt creation. Errors distinguish basic embeddings, custom dimensions and base64 support; callers can choose an embedding model, omit dimensions or use float encoding as applicable. A successful response uses the public model alias and must include one correctly shaped embedding for each input item. See Model routes for setup and pricing bounds.

This contract covers the implemented OpenAI-compatible text embedding operation only. The declared route flags are configuration assertions, not conformance results; native Anthropic and Bedrock embeddings, provider-specific conformance suites, and other input modalities are not implemented.

Automatic gateway activity and task correlation

Section titled “Automatic gateway activity and task correlation”

Every model request admitted to a supported Niu inference route is recorded automatically with its operation and attempt, public model alias, execution status, timing, usage confidence, provider-reported token counts and any known settled customer charge. Request and response content is retained separately for 24 hours unless explicitly disabled with x-niu-log-payloads: false; see Request content in Logs. Missing usage or cost remains unknown. This is the default source for request activity; a user does not need to export or import gateway logs.

GET /api/v1/organizations/{organization}/projects/{project}/requests/{attempt} returns one request’s metadata independently of list pagination and filters. It requires read access to that workspace and returns 404 when the request is absent from that scope. The response uses the same customer-safe fields as the request list; Provider costs are excluded. Payload content is retrieved separately.

For retained unsent attempts, nullable admission_denial records checked request-rate refusals: key_request_rate_disabled for RPM zero and key_request_rate_exceeded for an exhausted positive limit. Its Gateway HTTP 429 and captured requested-key name are diagnostic provenance, not upstream execution, usage or billing attribution. Missing observations remain unknown; historical records are not reconstructed from current key settings. This recording scope covers the durable prepared-attempt path; priced and batch admission are not implied. Recorded-failure and key filters include this saved evidence only while the attempt remains unsent.

GET /api/v1/organizations/{organization}/projects/{project}/requests?limit=50 returns the newest gateway attempts first. Limits range from 1 to 100. Optional from_ms and to_ms bound creation time (from_ms inclusive, to_ms exclusive); model_alias, key_id, and status narrow the same workspace feed. Status values are not_sent, may_have_executed, confirmed_completed, confirmed_not_executed, output_withheld, delivery_failed, and recorded_failure. The first four filter Provider execution state; output_withheld selects recorded blocked or indeterminate output inspection. recorded_failure selects saved upstream failure or unsent Gateway admission-denial evidence; it does not infer failure from unknown usage or execution. delivery_failed selects recorded delivery HTTP errors (400–599), independently of Provider execution and customer charges. http_status accepts an exact code from 100 to 599 or unknown for absent delivery status; it combines with the other filters. Unknown does not mean successful, failed or not charged. The summary’s delivery_statuses counts each recorded code and a nullable unknown category across the full selected range in its consistent read snapshot. A Provider-completed request can still have withheld output and incurred customer charges. The endpoint returns data, a nullable next_cursor, and a summary computed over the complete selected filter range, independent of the current page. Pass the previous attempt UUID as after to continue with older matching entries. Pages are newest first; this is a live traversal, not a snapshot across pages. It requires workspace read permission or an installation administrator credential. Each record includes attempt_id, operation_id, optional api_key_id and key_name, optional task_id, optional task_evidence, public model alias and the nullable provider_model reported by the upstream provider, created_at, dispatched_at, completed_at, duration_ms, execution, nullable output_guardrail_outcome, usage_confidence, nullable prompt/completion token counts, and nullable customer charge currency, amount and status. A null output_guardrail_outcome means no inspection outcome was recorded; it does not establish delivery or content protection. Token and money quantities are exact decimal strings. task_evidence is the latest supplemental execution record for the same task ID in this workspace; it includes its scoped execution ID, source, record ID, coverage assertion and authority/result pairs, but no imported spans. Fetch metadata-only spans and causal links from /api/v1/organizations/{organization}/projects/{project}/executions/{execution} when an operator opens the trace. Unsettled or unpriced requests can have unknown cost; their absence from a cost ledger does not mean zero spend.

Request listing and CSV export accept sort=time_desc (default), time_asc, latency_desc, input_desc or output_desc. Sorting covers all matching requests before pagination. Known measurements precede unknown ones; latency uses complete request timing or historical complete duration, never an interrupted timing as a complete latency. Time and attempt ID break ties. Keep the same filters and sort when passing next_cursor as after. Traversal is live: measurements completing between pages can move a request in the ordering. Use CSV for a single-statement view of the selected range. Unknown sort values return HTTP 400. Customer charges are not ranked across different currencies.

GET .../requests/export downloads customer-safe CSV for the same date, model, API key and execution-status filters. It reads the range in one database statement, independently of the paginated Logs page. Workspace read access is required; inference keys cannot export. The response is an attachment with Cache-Control: no-store. Internal identifiers, task records, payloads, credentials and Provider commercial data are excluded. Unknown values remain empty cells, with usage and charge status alongside them. Token counts and customer nanounits preserve their exact decimal digits. Formula-like text cells are prefixed with an apostrophe for spreadsheet safety. Exports over 10,000 requests return 413 with instructions to narrow the filters; they are never silently truncated. Pagination parameters are rejected.

The range summary reports matched request count, requests with provider-reported usage, exact prompt/completion token totals, requests with complete timing, average complete gateway duration, matching P50/P95/P99 latency percentiles with sample count and boundary, reported cache-input/reasoning-output category sums with reported and unknown request counts, unresolved and unpriced customer charges, customer charge totals by currency, and usage breakdowns by model and workspace API key. A missing price or unsettled attempt remains unknown and is not converted to zero.

charges_by_model and charges_by_key report full-range customer ledger amounts separately by currency, within the same summary snapshot and filters. Amounts are exact decimal strings in nanos; missing settlement produces null currency and amount, with separate unresolved, unpriced and not-charged request counts. These counts and charged requests partition each row’s request count. Key identifiers are API references for scoped drilldowns, not display labels. These breakdowns contain no Provider purchase costs or margins.

New admitted requests include a nullable timing object in the workspace request feed: dispatch_ms, headers_ms, first_output_ms, total_ms, complete and http_status. Offsets use a monotonic gateway clock from request handling, independent of payload capture. First output is measured from a meaningful streamed Chat event, including text, reasoning, refusal or tool-call output; role-only events, keepalives and usage records do not count. Nonstreamed requests leave first_output_ms unknown.

Logs draws preparation, first-output wait and output-stream duration on one scale. Preparation includes validation and admission. Wait includes network and upstream processing; Niu cannot split those without upstream spans. Output duration includes delivery and terminal processing, so tokens per second describes the observed output stream, not pure model compute speed. Interrupted responses retain an incomplete interval, including cancellation after dispatch but before headers; headers_ms and http_status then stay null. Process crashes and cancellation during admission acknowledgement may leave phase timing unavailable. Older requests are not backfilled.

New Chat Completions, Responses and embeddings requests retain content in Logs by default. Send x-niu-log-payloads: false to opt out for a request. In dashboard Chat, turn off Save payloads in Logs in the composer settings before sending. This does not apply retrospectively to earlier requests.

Captured content is stored separately from accounting records for 24 hours. Capture is bounded to 1 MB per side; a retained request exceeding the request capture limit is rejected. Streaming responses are retained as streamed text, with incomplete and truncated responses labeled. HTTP headers are not retained. Known credential fields in request objects are removed, including Authorization, Proxy-Authorization, Cookie, Set-Cookie and API-key header names. Arbitrary secrets inside prompts are not automatically redacted. Response capture excludes confidential Provider cost metadata. Historical JSON and SSE responses are also sanitized when read. If a malformed or incomplete structured response cannot be safely serialized, the read returns HTTP 503 without its raw body; accounting and timing metadata remain available independently.

An authorized workspace reader can fetch retained content with GET /api/v1/organizations/{organization}/projects/{project}/requests/{attempt}/payloads. The response contains data with request, response, content_type, complete, truncated and expires_at, or null when content was not captured or has expired. Workspace write permission is required to delete it using DELETE at the same path. Content deletion does not delete accounting records. A durable content-free deletion marker prevents late capture or retries from recreating explicitly deleted payloads. Deletion before capture also prevents that attempt’s content from being stored.

An application or agent adapter can send the same optional X-Niu-Task-ID header on every inference call belonging to one task. Chat completions, Responses and embeddings accept 1–200 printable ASCII characters. Niu stores the value as opaque operation metadata and never forwards it to the provider. Activity without this header is still retained and remains visible as individual model requests. The header only groups model calls: local tool work, validation and acceptance need separate adapter events and are not inferred from gateway traffic.

Task correlation covers only model requests handled by Niu. External model calls, agent tool events, task acceptance, and subscription usage are outside Niu’s collection scope. Niu does not expose execution or agent-usage import APIs.

Niu organizes HTTP endpoints into two public prefixes:

  • Developer & Inference Data Plane (/v1/* and /v1beta/*): Model discovery (GET /v1/models), API key self-introspection (GET /v1/key), generation lookup (GET /v1/generations/{id}), text inference (POST /v1/chat/completions, POST /v1/responses, POST /v1/messages, POST /v1beta/models/{model_action}, POST /v1/embeddings), and media/video generation (GET /v1/media/capabilities, POST /v1/video/jobs, GET /v1/video/jobs, GET /v1/video/jobs/{id}, POST /v1/video/jobs/{id}/cancel, DELETE /v1/video/jobs/{id}, GET /v1/video/jobs/{id}/results/{kind}, POST /v1/video/jobs/{id}/results/{kind}/refresh). Authorizes either a workspace API key (Authorization: Bearer <niu_api_key>) or an authenticated console session paired with X-Niu-Key-Id: <key_uuid>.
  • Control, Workspace, Provider & Commercial Plane (/api/v1/*): Authentication, user sessions, organizations, workspaces, unified workspace API key management (GET /api/v1/workspaces/{workspace}/keys, POST /api/v1/workspaces/{workspace}/keys, GET /api/v1/workspaces/{workspace}/keys/{key}, PATCH /api/v1/workspaces/{workspace}/keys/{key}, DELETE /api/v1/workspaces/{workspace}/keys/{key}, POST /api/v1/workspaces/{workspace}/keys/{key}/rotate), request diagnostics, billing, Provider directory and offers, upstream API connections, model routing, pricing, and platform settings. Authorization is operation-specific (workspace member session, Provider membership, or platform authority). Legacy /api/v1/* paths remain supported at runtime for backward compatibility.

API key self-introspection and generation lookup

Section titled “API key self-introspection and generation lookup”
  • GET /v1/key returns the authenticated API key’s label, status, expiration, model access mode, allowed models, request-rate and token-rate limits, concurrency limit, and customer spending allowance (limit_nanos, committed_nanos, remaining_nanos) without exposing internal UUIDs.
  • GET /v1/generations/{id} returns customer-safe execution metadata, token usage, latency, and settled customer charge (total_cost_nanos, currency) for a single attempt ID owned by the caller’s workspace, omitting confidential Provider costs and internal route identifiers.

Installation administrators can read persisted platform upstream accounting for a workspace. These compatibility endpoints are procurement controls, not customer billing APIs. Ordinary workspace sessions and Provider memberships do not grant access.

  • GET /api/v1/organizations/{organization}/projects/{project}/budget returns data with currency, lifetime limit, reserved exposure and settled cash spend, or null when no budget exists.
  • GET /api/v1/organizations/{organization}/projects/{project}/costs?limit=50 returns settled entries and a nullable next_cursor. Pass that UUID as after to continue; limits range from 1 to 100.

All monetary and token values in these responses are decimal strings to preserve 64-bit integer precision in browser clients. Monetary amounts use billionths of the named currency. Each entry retains its attempt and price revision, separate API-equivalent and cash costs, token evidence, and a flag for usage exceeding reserved bounds.

Pages traverse ascending attempt UUIDs, not chronological order. This is a live view: newly settled entries may require a fresh traversal. Unsettled attempts are excluded; an empty page does not prove zero cost. Reserved exposure remains visible in the budget. Subscription fee allocations and capacity reports are not yet included.

Reporting requires installation administration even when the caller has workspace read permission. The reporting endpoints do not create prices, settle attempts, or enable automatic gateway pricing. Customer-facing request charges, Usage and Billing are serialized separately and never substitute these upstream amounts for customer charges.

Send POST /api/v1/organizations/{organization}/projects/{project}/budget with an administrator token and a body such as:

JSON
{"currency": "USD", "limit_nanos": "100000000000"}

This creates a USD 100 lifetime upstream budget for the workspace. It does not set a customer charge limit or an invoice amount. Amounts must be nonnegative decimal integer strings, with no exponent or fractional notation, within the signed 64-bit range. Currency is a three-letter uppercase code; no currency conversion is performed. Concurrent creation has one winner; an existing budget returns 409 without changing its limit, reservations or spend.

Current admission behavior: supported priced routes reserve their configured input/output bounds before dispatch; insufficient funds or a missing matching-currency budget prevents the upstream call. Once a workspace has an upstream budget, shared-route dispatch requires a trusted held reservation. Unpriced shared requests without such a reservation are rejected. Authorized owner-funded personal Chat and video routes are excluded from platform procurement accounting; their current permissions and Guardrails still apply. Existing dispatched attempts are not retroactively reserved. Provider billing bounds still require qualification: understated bounds can produce an overrun, which is recorded as liability. This is not a universal guarantee against upstream billing outside those bounds. Customer Usage does not expose procurement-budget management.

Shared upstream connections persist in PostgreSQL and are managed with installation authority or an explicitly granted platform-administrator role:

  • GET /api/v1/vendors lists all configuration metadata, including disabled configurations, without credentials. Optional supplier filters by explicit Provider business ownership. The response is one unpaginated data array without a silent row cap; memory use grows with list size.
  • POST /api/v1/vendors creates a vendor with a write-only api_key.
  • PUT /api/v1/vendors/{id} updates metadata, enabled state or the credential using expected_revision.
  • GET /api/v1/vendors/{id}/models lists all of the vendor’s mappings, including disabled mappings, in alias order. This compatibility endpoint returns one data array without pagination; it does not silently truncate at 1,000 rows. Large lists still consume response memory proportional to their size.
  • POST /api/v1/vendors/{id}/models creates a mapping without a revision or updates it using the current expected_revision.
  • POST /api/v1/vendors/{id}/check with { "alias": "team/fast" } performs a non-inference GET /models check. The check is capped at five seconds and 2 MiB, blocks redirects and private-network destinations, and returns only a status plus whether the exact upstream model ID appears in the provider catalog. Provider response content and credentials are never returned. A catalog listing does not prove inference access or quota; use Chat to test a real request through Niu.

A Provider can own multiple independently configured credentials, and each credential can bind multiple model aliases. Workspace key grants apply to each requested alias even when aliases share a credential. See the current multi-key and multi-model verification for the exercised update, disable, restart and billing behavior.

On a model update, omitting pricing preserves its exact stored value; explicit null clears it. Stale updates return 409. Responses use Cache-Control: no-store. Ordinary organization and workspace roles cannot administer these platform resources without an explicit platform-administrator grant. See Model routes for encryption, precedence and bootstrap behavior.

GET /v1/video/jobs/{id}/results/video returns the authorized media file, not a private upstream URL. A saved succeeded status does not guarantee that the upstream result remains downloadable. Use the repository command scripts/verify-video-result.py to read an existing job, download its current result and independently decode the final file with FFmpeg. It makes no submission or refresh request and keeps the workspace key in an environment variable. See the saved-result verification instructions for private artifacts, prerequisites and the precise verification scope.

The actor-owned workspace video-intents API saves a validated text-video request before explicit submission. PUT /{intent} saves a fresh identity, GET /{intent} restores its content and original job/preparation state, and POST /{intent}/submit explicitly submits or replays it with expected_revision. The collection GET provides a scoped metadata index; DELETE clears content while retaining a non-reusable identity. Current key authorization follows only the original rotation lineage. Reads never submit, poll upstream or reserve funds.

See the generated operation schemas and durable Video intent contract for request bodies, actor isolation, 30-day content retention, deletion semantics and current verification limits. Images/references and customer-funded video qualification remain outside this verified subset. The Generations dashboard integrates saved-intent restoration, including original input, retained preview and diagnostics after key expiry. Successful reference submission and the full shared-output lifecycle remain separate verification requirements. See Generations for the supported browser workflow.

Video timing responses include a result phase for result retrieval. Its elapsed time measures the upstream fetch and bounded body read. received means the Gateway obtained the media bytes; current access is checked again before delivery, so it does not prove client receipt. Retrieval failures record unavailable, with the upstream HTTP status when explicitly classified by the adapter; otherwise it remains unknown. These records never create another generation or customer charge. Authorization failures before retrieval do not create a network span. A cancelled handler or failed diagnostic write may leave no timing entry.

Video transport timing entries also expose nullable upstream_http_status for submission and refresh HTTP failures. Historical and unclassified spans retain null. This diagnostic never changes the saved generation state or proves that a charge or reservation can be released.

Video submission HTTP errors now retain a safe upstream_http_error classification and status code in workspace request diagnostics. The create response remains 202 with submission_unknown; this does not prove nonexecution, release a held customer liability or authorize another submission. Idempotent replay restores the same job reference. See the generated create contract.

GET /api/v1/organizations/{organization}/projects/{project}/requests and its /export CSV endpoint accept optional operation_id (UUID). The filter selects execution attempts belonging to that operation within the authorized workspace; list summaries use the same filter. An unknown operation or one in another workspace yields no matching rows. Invalid UUID syntax returns 400. Other filters combine with it, and existing pagination/export limits still apply.

Use the operation_id returned by request metadata for correlation; keep internal identifiers out of product display labels. The JavaScript SDK exposes this as operationId in listGatewayActivity and exportGatewayActivity. This read-only filter does not initiate retries. Nullable retry metadata supplies each attempt’s ordinal, predecessor, maximum attempt count and policy revision.

Customer tariff publication accepts optional minimum_charge_nanos, an exact nonnegative decimal string within signed 64-bit range. A new tariff defaults to zero; replacing an existing nonzero minimum requires an explicit value, and "0" disables it for future requests. Null and malformed amounts are rejected.

Known completed usage costs the greater of the rounded token amount and this minimum. Admission reserves the greater of the token bound and minimum, including when token rates are zero. Unknown usage remains unresolved; a client disconnect does not authorize charging the minimum or releasing its outstanding reservation. Existing history is not repriced, and this field does not configure Provider or video charges. Invoice lines and model-price reads expose the pinned/current minimum as appropriate. Internal balance refunds remain bounded by the original charge, restore the refunded key allowance once and preserve historical invoice pricing. The SDK uses the same minimum_charge_nanos field. See the contract and actual verification.

A current gateway recovered a previously generated personal video after the transport-status migration, queried its real upstream reference and retained the same successful job across restart. Downloaded bytes matched the original artifact’s SHA-256 and independently decoded as H.264 video. No new generation or customer charge was created. This verifies that recovery path, not customer-funded video settlement. See the recorded recovery evidence.

Customer tariff publication now accepts request_fee_nanos as an exact nonnegative integer string. A known completed request is charged the greater of its rounded token amount plus this fixed fee and minimum_charge_nanos. Admission reserves using the same formula; rejected or unresolved requests do not invent a fee. Historical tariff versions remain pinned. Replacing a nonzero fee requires an explicit value, and "0" disables it. The SDK uses the same field. See the pricing rule and supported boundary.

Current-input fixed-fee verification now includes buffered and streamed Responses, Chat/Responses/embeddings sharing one account concurrently, and bounded idempotent internal refunds. Independent provider-response arithmetic and database ledger reads agreed; restart retained the charges and restored allowance. See the protocol and refund evidence.

Fixed-only pricing was also exercised with two gateways and workspaces competing for company credit sufficient for one request: one completion, one HTTP 402 and one exact debit. A separate SIGKILL after actual streamed content retained unknown usage and its reservation without inventing a fixed-fee charge or retry. See the contention and crash evidence.

Fixed-fee admission rejects a token-plus-fee amount that overflows signed 64-bit nanounits with HTTP 400. A representable amount without sufficient spending capacity returns HTTP 402. Actual API requests and independent SQL verified that neither case dispatched upstream or left financial reservations; see the admission boundary evidence.

GET /v1/models is included in the handler-generated OpenAPI. Model customer_pricing contains the authenticated workspace’s current selling tariff, or null. Token rates use nanounits per million tokens; minimum_charge_nanos and request_fee_nanos are per-request currency nanounits. Keep every amount as a string. The SDK exposes both fee fields on model prices and invoice lines. Model discovery does not guarantee admission or upstream availability. See the actual scoped price-read verification.

Use GET /api/v1/organizations/{organization}/projects/{project}/billing/tariffs/{model}/history or SDK getCustomerTariffHistory to read immutable customer text prices. The response includes the current revision and newest-first pages with next_before; all monetary fields remain strings. Follow the cursor to continue and refresh the first page to see newly published prices. Missing/foreign cursors return 409; inaccessible workspaces or unknown model tariffs return 404. Provider procurement prices are excluded. See the contract and actual pagination evidence.

Customer tariff history accepts scoped management readers, including the owner and viewer roles exercised in the actual authorization run. A workspace inference API key cannot read this management endpoint; use its authorized /v1/models price projection instead. Cross-workspace history remains concealed with 404. The frontend integration inventory now lists publication, current prices and immutable history together.

When cached_prompt_rate is set, price uncached input, cached input and output separately, sum their exact amounts and round upward once. Then add request_fee_nanos and apply minimum_charge_nanos to the combined amount. Missing required cached usage remains unresolved; a fixed fee does not replace the missing evidence. All rates and fixed amounts retain their pinned revision.

Actual nonzero-cache completions exercised both an additive fee and a minimum above the combined amount. Saved provider usage and reopened database records matched the charges, invoice and refund balance. See the formula and verification scope.

GET /api/v1/providers/{provider}/offers/{offer}/revisions/{revision} reads a known historical procurement quote. Installation administration or active membership in that Provider is required; company ownership grants no access. The Provider, offer and revision must match. Missing or inaccessible quotes return 404. The JavaScript SDK exposes getSupplierOfferRevision.

Text rates remain exact strings, with nullable cached-input pricing. Media revisions have null text-price fields and use the separate media rate-card API. Reading a quote does not activate or qualify it. Keep procurement information out of customer workspace screens. The handler-generated OpenAPI now documents the response variants and authorization boundary. Current HTTP reads matched four saved text revisions; active Provider viewer access, company-role denial and membership revocation were independently checked against database records. Media quote reads remain unverified.

GET /api/v1/providers/{provider}/offers/{offer}/revisions lists historical quotes without requiring a known revision ID. The same Provider membership or platform authority applies. Use limit (1–100, default 50), then pass next_before as before while has_more is true. Each entry adds is_current; the response also includes current_revision. Unknown or foreign cursors return 409, and inaccessible Provider/offer identities return 404.

The SDK exposes listSupplierOfferHistory. Read the pagination and confidentiality contract before integrating. These are procurement prices, not customer billing data.

Platform administrators can read or update /api/v1/vendors/{vendor}/request-rate-limit and read its /history. PUT requires requests_per_minute (explicit null for unlimited, zero to stop dispatch) and the exact string expected_revision. Limits are independent of customer key RPM and shared across gateway instances using the same saved credential. History supports before_revision and limit.

A local dispatch refusal returns 429, upstream_request_rate_exceeded and a conservative Retry-After: 60. It does not send another upstream request. The SDK provides getVendorRequestRateLimit, setVendorRequestRateLimit and listVendorRequestRateLimitHistory. See the dispatch semantics and verification boundary.

Platform administrators can read GET /api/v1/vendors/{vendor}/cooldown, or use SDK getVendorCooldown. The response reports policy_revision, failure_threshold, window_seconds, cooldown_seconds, active, nullable cooldown_until, and qualifying_failures. Company-scoped administrators cannot read this state.

Three new, qualified canonical OpenRouter text authentication refusals in a 60-second rolling window pause new selection for 60 seconds. Further qualifying in-flight failures may extend the deadline. Timeouts and uncertain execution never count. Direct selection returns 503 upstream_credential_cooldown; a pool with no eligible mapping returns 503 route_pool_unavailable. Pinned requests continue. State survives restart and credential edits; expiry restores eligibility automatically without an upstream probe or administrator republish. This fixed policy has no write endpoint. See the policy and verification boundary.

Video model attribution in request diagnostics

Section titled “Video model attribution in request diagnostics”

The existing provider_model field now retains a model explicitly returned by a validated video query. Missing Provider model fields remain unknown; Niu does not substitute the configured mapping. Existing completed jobs can gain this field through an authorized refresh that reports it, without another generation. A Logs read alone does not query upstream. See model attribution and retention boundaries.

Fresh video submissions retain the inspected Niu request and the Niu creation response through the existing scoped payload read/delete APIs, for up to 24 hours. Use x-niu-log-payloads: false to opt out. Saved-intent submission captures the inspected video request, not its revision-only envelope. Replay never recreates capture. These are Niu API bodies, not raw upstream transport or generated files; a completely captured 202 response does not mean generation completed.

See video request payloads for bounds, authorization and retention semantics.

Authentication failure and unresolved charges

Section titled “Authentication failure and unresolved charges”

A 401 does not universally prove that a Provider did no work. Managed text requests pin the reviewed canonical OpenRouter nonexecution policy at admission; custom endpoints using the same adapter and older requests without that policy retain uncertainty and their applicable holds. Customer diagnostics preserve the HTTP failure separately from execution and charge state. Do not treat every 401 as a refund or permission to retry.

See qualified nonexecution policy for the implemented boundary and actual verification.

The gateway checks every retained Provider inference and asset-management credential revision before listening. A missing or incompatible deployment key fails closed. Revoked asset credentials remain checked until explicitly erased; startup does not delete or re-encrypt them. Restore the matching key rather than erasing data to bypass the diagnostic. See startup validation and its limits.

GET /api/v1/providers/{provider}/settlements provides history beyond the Provider dashboard’s latest 100 payment records. Platform administrators or active members of that Provider can read it. Use limit (1–100), before, currency, from_ms (inclusive) and to_ms (exclusive); keep filters fixed while following next_cursor until null. Time bounds are Unix milliseconds. The SDK provides listSupplierSettlements, with fromMs and toMs query properties.

Amounts are exact decimal strings. Rows contain payment-record metadata and exclude customer and request details. Reads do not record payments or transfer funds. See the contract and verification boundary.

Graceful shutdown now waits up to ten additional seconds for registered request timing and content writes after HTTP and financial writers drain. A database stall beyond that window emits request_diagnostics_shutdown_timeout; forced termination or storage failure can still leave missing diagnostics. Missing content is not permission to retry an uncertain upstream operation. See the actual shutdown verification and limits.

GET /api/v1/organizations/{organization}/projects/{project}/billing/invoices continues beyond the overview’s latest 100 invoices. Use limit (1–100), before, currency, from_ms and to_ms, then follow next_cursor until null. These time filters describe invoice creation time; each returned invoice’s from_ms / to_ms still describes its billed usage interval. The SDK provides listCustomerInvoices with shared LedgerHistoryQuery (fromMs, toMs).

The endpoint enforces workspace read scope and returns customer amounts only. Posted balance debits settle invoices even when approved credit was used; they do not become another unpaid invoice debt. Reading history creates no payment. See the contract and 152-invoice actual verification.

Request detail may report failure.kind: response_stream_cancelled with null upstream_http_status when the body is dropped before terminal or explicit upstream-failure handling. This does not identify who cancelled delivery or prove that upstream execution did not occur. Headers may already be HTTP 200 while timing/content capture remains incomplete.

Unknown usage, financial reservations and key concurrency occupancy remain; cancellation does not trigger a retry or credential cooldown. Completed streams and known upstream errors retain their own outcomes. See the actual cancellation, completion and timeout verification.

Platform administrators can use GET /api/v1/providers/{provider}/earnings to page beyond the administration overview’s recent earning preview. The SDK exposes listSupplierEarnings; exact amounts remain Provider liabilities. Provider membership does not grant this request-level reconciliation access. Internal selection IDs must not appear in product UI. The existing settlement write still revalidates unpaid selections and requires confirmed payment evidence. Nonempty pagination and full Provider reconciliation remain unverified.

Platform customer-price configuration reads

Section titled “Platform customer-price configuration reads”

Explicit platform administrators can discover named company/workspace pricing targets with GET /api/v1/pricing/targets, then read current selling prices at GET /api/v1/pricing/organizations/{organization}/workspaces/{project}/tariffs. Both use after, limit (1–100) and next_after pagination. Append /{model}/history to the tariff route for immutable history (before, limit, next_before). These reads exclude customer balances, usage, statements, request content and Provider procurement. Customer-scoped billing access remains independent. SDK methods are listPlatformPricingTargets, listPlatformCustomerTariffs and getPlatformCustomerTariffHistory.

Recorded preparation-policy refusals return HTTP 403 with error.type: "guardrail_denied", indicating rejection before model dispatch. The response does not expose matched input or rules. Read authorized preparation diagnostics for the recorded reason; do not classify every 403 as Guardrails. Administrative permission failures retain their separate error type.

Buffered output withholding after dispatch uses HTTP 403 with error.type: "guardrail_output_withheld". Generation charges may apply even though the output is not delivered. Inspect authorized request Guardrail diagnostics for a saved outcome; do not automatically retry the operation.

POST /v1beta/models/{alias}:generateContent is available for explicitly opted-in static or managed gemini routes. URL-encode the alias, including any slash, and authenticate with a Niu workspace key. Supply textual contents and a bounded generationConfig.maxOutputTokens. Native tools, media, cached resources, thinking configuration and streaming are unsupported and rejected before dispatch. Existing prepaid pricing, permissions and key limits still apply.

The SDK exposes client.generateContent(alias, body) using a base URL ending in /v1. Generated contracts list the exact supported fields. Actual negative paths, input redaction, retained upstream rejection and restart were verified; successful Google generation, output processing and settled billing remain unverified. Provider credentials accept adapter: "gemini"; model mappings require capabilities.supports_generate_content: true. Discovery and checks use native Google authentication and bounded catalog reads. See the implementation and verification boundary.

POST /v1/messages supports bounded nonstreaming text on explicitly opted-in OpenRouter or Anthropic mappings. Set capabilities.supports_messages: true for managed mappings. Anthropic mappings can save conservative route prices through the same Provider configuration API; customer selling tariffs remain separate. Missing usage stays unknown. Unsupported reasoning rates, including explicit zero rates, are rejected before dispatch. An upstream refusal with uncertain execution retains its priced reservation for reconciliation.

Actual configuration, prepaid denial, price-category rejection, output bounds and refusal persistence across restart are verified. Successful direct Anthropic settlement remains unverified. See the native protocol scope.

Company owners/admins and installation administrators can inspect outstanding holds at GET /api/v1/organizations/{organization}/billing/reservations. Use limit (1–100), optional currency, and before from next_before. Released reservations disappear from results but remain valid cursors. Responses include workspace/key names, model, current execution/usage state, and exact customer reservation and outstanding amounts. Internal identifiers are links, not display labels. Provider costs and upstream credentials are excluded.

This is a diagnostic read, not a release-funds or retry operation. Unknown execution/usage stays unknown. Separate pages are independent observations. A completed response with incomplete usage remains usage_unknown; a known-usage response awaiting accounting recovery reports settlement_pending. Actual calls verified both states across restart and release of only the recoverable hold. The SDK exposes listCustomerBalanceReservations; see the scope and actual verification.

Chat and Responses route-pool admission can return HTTP 504 with error.type: "request_deadline_exceeded" when the original request deadline expires during preparation or before committed dispatch. That attempt was not sent upstream. A retry operation may already contain an earlier upstream rejection; preserve any returned x-niu-operation-id and x-niu-attempt-id headers when linking to request diagnostics.

Display this as a request timeout rather than a database availability failure. This classification does not authorize replay of an uncertain attempt or an already returned stream. Inspect saved request state before deciding whether to start a new operation. Other HTTP 504 errors do not inherit this nonexecution guarantee merely from their status code.

See the bounded retry and deadline contract.

HTTP 409 with guardrail_admission_conflict means the inspected policy no longer permits dispatch under the current workspace/key policy. The rejected attempt was not sent upstream. Paid admission retains an unsent attempt and its safe rejection audit, releases its customer hold, and creates no customer charge. A new request must be inspected under the current policy.

Messages keeps its native error envelope; read x-niu-error-code for the Niu classification. Generic conflicts and unknown database failures retain their separate meanings. See policy-race behavior and evidence. The Generations dashboard integrates saved video intent restoration, including original input, retained preview and diagnostics after key expiry. Successful reference submission and the full shared-output lifecycle remain separate verification requirements. See Generations for the supported browser workflow.

阅读 API 快速入门 了解如何发起 HTTP 请求,或阅读 SDK 快速入门 了解带类型的 JavaScript 调用与流式传输。

REST 接口规范 由完整的 OpenAPI 契约自动生成。SDK 参考 由公开的 TypeScript 类型声明自动生成。对于需要消费接口规范的工具,可下载 打包的 OpenAPI JSON。接口变更会在 CI 中与生成的产物进行比对校验。

管理自动化使用具体操作所需的权限;客户工作空间密钥不是平台管理员凭据。请阅读 管理员访问权限 与 安全概览 了解初始配置、登录、会话恢复与吊销。具体的身份认证与会话 Schema 详见 REST 参考。

请求日志 描述了 Niu 牛元处理请求时记录的用量与耗时信息。可选的客户端关联元数据不会将这些记录转化为外部智能体的执行追踪链路。Niu 牛元不负责任务编排、外部工具日志或结果评估。

任务 从这里开始
发送应用请求 API 教程或 SDK 教程
查看字段、响应或认证要求 自动生成的 REST 规范
查找带类型的客户端方法 自动生成的 SDK 参考
返回 Chat 或 Video 工作 生成
理解已保存的请求或费用 请求日志与用量和计费

平台管理 介绍了模型供应商配置、客户价目表、支付集成与品牌定制。NiuAdminClient 参考 包含了自动生成的客户端接口定义;指南文档不再重复列出方法签名。

JavaScript SDK 提供了 admin.getChatDraft() 与 admin.saveChatDraft()。在保存或清空草稿前请先读取当前修订版本(revision);若发生版本冲突,需显式重新加载并合并协调。保存草稿不会提交模型推理请求。

主 OpenAPI 文档中包含的 客户计费契约 涵盖了工作空间授权的账单汇总与账单明细行读取。客户扣费使用独立的销售价目表,与模型供应商采购价格解耦。未定价的请求不会被假定为免费;未决费用保持未知状态。货币金额与聚合计数均采用精确的十进制整数字符串表示。工作空间计费价目表列表与模型发现接口中的客户价格包含所有匹配的已保存价目表,不会在 1,000 条记录处静默截断。这些兼容性响应保持不分页,其内存占用与列表大小成正比。

账单文本明细行保留计费时所使用的价目表修订版本及选定的上下文阈值,而不会替换为当前最新的模型价格。同一修订版本可能会针对不同的上下文阈值生成多条明细行;客户端必须保留这些独立的分组。缺失的缓存读取(cache-read)、缓存写入(cache-write)与推理思考(reasoning)用量保持未知状态。类别费率为 null 表示绑定的价目表中未配置该类别;省略的费率则表示未知。选定的上下文阈值为 null 表示使用基础价目表,切勿将其显示为零阈值。在展示或核对金额时,请使用精确的整数字符串。

发布价目表、创建账单以及记录已确认的外部付款均需要实例级管理权限。账单周期使用 UTC 派发时间戳,包含起始时间 from_ms(闭区间)且不包含结束时间 to_ms(开区间),跨度上限为 366 天。重放同一账单创建请求时,请保留调用方的幂等键。周期重叠、存在未决的计费请求以及重放参数发生变更均会产生冲突;客户端不得通过伪造新幂等键来重试此类冲突请求。

JavaScript SDK 提供了 getCustomerBilling、publishCustomerTariff、issueCustomerInvoice、getCustomerInvoiceLines 和 recordCustomerInvoicePayment 方法。其自带的 inspect-billing.mjs 示例可读取最近 100 张账单,并使用精确整数运算核对明细行总额。创建账单不会发送账单通知或执行收款,记录付款也仅登记已在外部确认完成的付款。请将管理凭据保留在服务端,且切勿在产品界面中展示内部账单 ID 或费率标识符。

已产生的文本请求费用即使超出最初的预占额度或已批准的企业授信额度,仍会保留其完整入账金额。因此,账户余额与可用容量可能变为负数。新的付费请求需要足够的可用容量,否则可能返回 HTTP 402 budget_exceeded;计费查询接口仍可正常访问。余额退款作为独立的账本条目记录,不会抹除原始扣费记录。费用对账 API 会将原始总费用与原始余额扣款进行比对,不会扣除退款金额。如需查看净资金余额,请查询余额账本。实际非空对账与退款验证记录 记录了当前的文本核算边界。重放同一管理操作时,请保留退款幂等键。

一次基于授信额度的实际运行验证了超支结算、跨重启拒单、幂等内部退款以及随后的真实模型生成完成。但这并不构成对银行原路退回或客户出资视频生成行为的验证。详见 实际企业授信验证证据。

经授权的个人上游路由由其凭据所有者出资,不会预占或扣减 Niu 牛元客户资金或平台采购预算。因此,已保存的工作空间采购预算本身不会阻止经授权的个人对话(Chat)或视频调用。当前的密钥/模型权限、安全护栏(Guardrails)与请求速率控制仍然生效。共享计费路由仍保留采购准入检查;这一区分不会授予访问其他企业个人凭据的权限。个人操作与客户计费操作在其各次尝试(attempt)绑定期间保持不可变的资金来源;候选路由选择无法在两者之间切换。对话路由池在遇到符合条件的 OpenRouter 立即认证拒绝(HTTP 401)后,支持一次受限的后继尝试;状态不确定的执行绝不会重试。个人文本请求会在单独的派发权限检查之前,原子化地准备其操作(operation)、路由与准入绑定。准备失败不会留下部分绑定的请求,但这并不会启用派发状态不确定后的自动重试。

共享视频路由保留原有的采购预算限制;个人视频路由不会预占或扣减该预算。个人视频调用仍会强制执行密钥 RPM 与并发控制。当渠道缺少受支持的 Token 准入上限时,配置了有限 Token 速率预算的密钥会以 422 key_token_bound_required 拒绝视频请求。

密钥消费限额适用于新的客户负债预占。请从消费限额 API 读取 committed_nanos 与 remaining_nanos;请保留这些精确的十进制整数字符串,切勿将其转换为浮点数金额。当实际消耗超过限额上限时,剩余可用额度(remaining_nanos)会被截断为零。限额上限不会截断已产生的费用,也不会取消正在进行的上游任务。密钥轮换(secret rotation)会保留相同的消费身份与已承诺金额。

在一次实际的流式文本请求中,输出超出了请求设定的上限:最初 1,000 nanos 的预占被释放,完整的 11,000 nanos 客户费用被入账,且轮换后的密钥显示剩余额度为零,并在重启前后均拒绝了后续请求。这是一项针对文本核算范围的观测验证,并不代表对媒体超支或所有模型供应商的准入认证。详见 验证详情。

平台管理员可以通过 GET /api/v1/pools/index 或 SDK 的 listModelRoutePools 方法发现已保存的路由池。传入 limit(1–100,默认 50),然后将返回的 next_after 作为下一页的 after 参数。该列表包含已启用和已禁用的配置。其基于别名的实时遍历并非一致性快照;若要查看当前游标之前新插入的别名,请从第一页重新刷新。现有的别名查询和修订历史端点保持原有响应格式不变。

推理模型发现会遍历所有已保存的路由池分页,而不会静默限制在前 1,000 个路由池内。已禁用和未授权的路由池仍会被排除。兼容性端点 /v1/models 的响应仍然返回完整列表;受限的数据库分批读取并不意味着返回固定大小的响应。推理发现在单个只读数据库快照中读取共享映射、个人所有权、模型供应商准入资格、冷却状态以及所有路由池分页。它在无需逐池查询路由或解密凭据的情况下组装模型目录。静态别名仍会被数据库别名覆盖(包括已禁用和外部个人的映射)。这是一个按次读取的目录快照,而非已发布的推理生成保证;实际的请求准入仍会检查当前的权限与凭据状态。管理端分页则保持为独立的实时遍历。

带修订版本的路由池更新仅对新请求的候选选择生效。禁用某个候选路由不会取消已通过该路由派发的生成请求。该请求会保留其原始映射和路由池修订版本以供诊断和核算;后续请求则可在新修订版本下选择其他符合条件的候选路由。客户模型别名与客户价目表仍与模型供应商映射保持分离。

该行为已通过实际的并发计费请求以及独立的费用/修订版本检查进行了验证。此外,在收到规范的 OpenRouter 立即 HTTP 401 响应且确认持久化未执行并释放预占后,对话(Chat)路由池可以尝试另一个凭据。在单个操作(operation)与截止时间(deadline)下最多允许提交两次尝试,同时保持客户价格与资金来源不变。其他错误以及已开始向客户端返回数据的流式响应均不会重试。详见 路由池契约与验证证据。

工作空间的请求列表与详情端点会报告客户模型别名、执行状态、上报的用量、客户费用以及已保存的阶段耗时。路由池所选的模型供应商映射及机密采购价格不属于客户计费数据。实例级管理凭据获取到的是相同的面向客户的详情结构,不会扩展包含批发采购成本。请求元数据响应使用 Cache-Control: no-store。

请按照 自动生成的请求契约 中的说明使用详情响应中的可空(nullable)字段。缺失的耗时或用量表示未知(unknown),而非实测为零。工作空间范围限制适用于每一个请求;不属于该工作空间的请求会返回 404。请展示有意义的模型/密钥名称与时间戳,而不要展示仅用于 API 路由的内部标识符。

GET /catalog/v1/models 与 /models/ 页面列出了操作员显式标记为 public_catalog = true 的模型别名。响应包含模型别名、声明的能力,以及可选的描述性目录元数据(如名称、上下文限制和模态);它省略了模型供应商名称、上游标识符、端点地址、凭据以及供应商采购价格。目录可见性并不授予推理权限。应用程序仍需使用带作用域的密钥调用 /v1/models 和各推理端点。

operator 是现有管理 API 契约中表示工作空间成员的名称;控制台界面中则使用 用户(Users)。账户使用各自的凭据登录,并获得其分配的角色与工作空间访问权限。实例初始设置凭据与成员会话及应用 API 密钥相互独立。密码会话 API 需通过配置 NIU_AUTH_PUBLIC_ORIGIN 显式启用,该值必须是不含路径、凭据、查询参数或片段的 HTTPS 源地址(Origin)。请在该源地址的 HTTPS 反向代理后部署服务。自助注册与身份联邦(Identity Federation)目前尚未实现。

PUT /api/v1/operators/{operator}/password 允许实例管理员或具有作用域的所有者(owner)为现有成员配置 email、password 以及可选的 expected_revision。首次设置密码时省略修订版本;重置密码则需要传入上一次返回的修订版本,并会原子化地吊销该成员此前的所有会话。密码长度要求至少 15 个字符且不超过 1,024 个 UTF-8 字节;空格与 Unicode 字符均会被原样保留。响应返回新的修订版本,绝不会返回密码哈希值。

POST /api/v1/auth/login 接收 email 和 password,并返回一个带作用域的 8 小时有效期 Bearer token 及会话元数据。它仅授予该成员现有的角色与工作空间访问权限,绝不会授予实例级管理权限。密码错误与未知身份返回相同的 HTTP 401 响应。持久化准入限流在 60 秒窗口内允许每个规范化邮箱尝试 5 次、每个实例尝试 120 次;超出限制的请求返回 HTTP 429 并附带 Retry-After: 60。这两个路由均将 JSON 请求体限制为 4 KiB,并将成功和错误响应标记为 Cache-Control: no-store。若请求包含浏览器 Origin 头,则必须与配置的源地址匹配。这些路由不会设置浏览器 Cookie;控制台使用下方独立的浏览器端点。未配置 NIU_AUTH_PUBLIC_ORIGIN 时,密码登录返回 HTTP 501。

对于同源浏览器客户端,POST /api/v1/auth/browser/login 使用相同的凭据与限流规则,要求提供匹配的已配置 HTTPS Origin,并设置一个 8 小时有效期的 Secure、HttpOnly、SameSite=Lax 仅限主机(host-only)的 Cookie。其返回的 JSON 仅包含会话元数据,不含 Bearer Token。共享成员鉴权会在每次请求时校验已保存的会话,并要求匹配的 Origin 或浏览器 Sec-Fetch-Site: same-origin 元数据;不匹配的 Origin 始终失败。重复的 Authorization 请求头会被拒绝。当提供 Fetch Metadata 时,即使 Origin 匹配,也必须仅包含唯一一个 same-origin 值。此 Cookie 路径绝不接受实例级管理令牌。POST /api/v1/auth/browser/logout 要求匹配的 Origin,吊销当前会话并使 Cookie 过期。已失效的会话仍可成功清除;存储层故障不会谎称已退出登录或清除 Cookie。控制台通过 GET /api/v1/auth/config 发现此模式,使用浏览器端点登录,并在不在浏览器存储中保存 Bearer Token 的情况下恢复服务端会话。真实 HTTPS 浏览器端到端验收测试仍在进行中。

PUT /api/v1/auth/password 允许任何已登录的成员角色使用 current_password 和 password 修改自己的密码。它不接受目标成员参数或邮箱;实例级凭据无法调用此接口。当前密码校验共享登录限流配额,新密码遵循相同的创建策略,且在校验期间若发生凭据修订版本变更,将返回 HTTP 409 而不会覆盖更新的凭据。修改成功后会吊销该成员的所有会话并返回 sign_in_required: true;其他成员不受影响。基于浏览器 Cookie 的请求要求匹配的 Origin,并在成功后使 Cookie 过期。修改失败会保留原有会话。控制台在账户设置中提供了修改密码功能;界面渲染审查与 HTTPS 浏览器准入验证仍在进行中。

GET /api/v1/auth/preferences 读取已登录成员保存的颜色模式偏好。PUT /api/v1/auth/preferences 接受 {"color_mode":"system"}、"light" 或 "dark" 作为 color_mode 的值。任何成员角色均可修改自己的偏好设置;实例级管理令牌与调用方指定的目标成员参数均会被拒绝。默认值为 system。偏好设置独立于个人资料修订版本存储在 PostgreSQL 中,浏览器存储仅作为临时缓存。控制台与内嵌文档控件共享这一已保存的偏好设置。基于浏览器 Cookie 的写入采用与资料修改相同的 Origin 检查;响应不可缓存,且请求体限制为 1 KiB。仅使用实例级管理令牌的显示选择没有可绑定的个人账户,仅保留在本地。

POST /api/v1/auth/logout 吊销 Authorization 请求头中的成员 Bearer 会话。任何成员角色均可退出登录;其他会话保持活跃。会话吊销及其审计记录是原子的,响应不可缓存,缺失、已过期或此前已吊销的凭据返回 HTTP 401。实例初始设置令牌不属于成员会话。即使未配置密码登录,此 API 仍然可用。控制台对 Cookie 会话使用浏览器退出登录端点,并在吊销失败时保留当前会话状态。

密码会话契约 详细记录了请求字段、角色限制、会话响应与失败状态码。

NIU_ADMIN_TOKENS 仍然是所有者(owner)级别的实例引导凭据。所有者可以通过 POST /api/v1/operators 创建具有 owner、admin 或 viewer 角色的持久化操作员,并通过 POST /api/v1/operators/{operator}/sessions 签发额外的定期过期会话。创建响应仅一次性返回 Bearer Token 并带有 Cache-Control: no-store;列表 API 仅返回身份、角色、会话 ID、过期时间与吊销元数据。删除单个会话或操作员即可吊销其访问权限。已吊销或已过期的令牌在下一次发起管理请求时将失败。

操作员及会话的创建与吊销还会在同一数据库事务中追加不可变的、仅含元数据的审计事件。事件会记录执行者是实例引导凭据还是带作用域的操作员、执行者操作员 ID(若有)、目标操作员/会话 ID、租户范围以及时间戳。审计事件绝不会存储 Bearer Token、令牌哈希或请求体。带作用域的所有者可以通过 GET /api/v1/operators/{operator}/events 分页查看某个操作员的审计事件;分页按时间戳和事件 ID 排序,限制为 1–100 条,并使用 next_cursor 实现稳定的向后翻页。

所有者(owner)可以管理成员。管理员(admin)可以读写管理资源,但不能管理成员。只读成员(viewer)仅具有读取权限。每个成员都拥有一个 organization_id,并可能带有一个将访问权限限制在单个工作空间内的旧版 project_id。所有者无法创建或管理超出自身权限范围的成员。控制台 URL 中的工作空间 ID 不会授予访问权限。GET /api/v1/session 返回调用方当前的身份、作用域与角色权限,且不会暴露任何凭据。

控制台的 GET /api/v1/workspaces 会列出当前管理员可见的工作空间及其所属组织。POST /api/v1/workspaces 在指定组织下创建新工作空间。组织管理员只能在所属组织内部创建工作空间;实例管理员则可以选择任意组织。如果实例中尚无任何组织,省略 organization_id 会先创建一个名为 Personal workspace 的组织。API 密钥、请求记录、预算与用量均归属于工作空间;project 这一名称仅保留在旧版 API 与存储契约中。

各项能力均按路由单独声明。config/niu.toml 中的标志位声明了经操作员验证的行为,并不意味着 Niu 牛元已对每个模型供应商的所有模型或端点完成了全面准入验证。对于下方契约中标记为不可用的功能组合,请求会在创建执行尝试(attempt)之前即被拒绝。

操作类型 OpenAI 兼容路由(provider = "openai" 或 "openrouter") 原生 Anthropic 路由 原生 Bedrock 路由
对话补全(非流式) 支持;工具调用与结构化输出子集需要配置独立的路由标志位 基础非流式适配器路径 基础非流式适配器路径
对话补全(流式) 支持;流式工具调用增量需要 supports_streaming_tool_calls 未实现 未实现
函数工具(Function tools) 开启 supports_tool_calls 时支持非流式工具调用透传;Niu 牛元不执行工具 未实现 未实现
结构化 JSON 输出 开启 supports_structured_output 时支持缓冲与流式 json_object / json_schema;流式增量在终态校验前仍为临时数据 未实现 未实现
文本嵌入(Embeddings) 仅在开启 supports_embeddings 时支持;自定义维度与 base64 输出需要配置各自的标志位 未实现 未实现
Responses API 开启 supports_responses 时支持缓冲与流式文本子集 未实现 未实现

原生 Anthropic 与 Bedrock 条目描述的是当前的非流式对话适配器路径,而非模型供应商一致性认证。工具调用与结构化输出能力被有意限制在 OpenAI 兼容路由上。计费功能适用于有界文本对话、Responses 和文本嵌入;文本嵌入仅预占输入容量,并按模型供应商上报的提示词(prompt)用量进行结算。计费对话支持文档中说明的纯文本函数工具多轮会话;Niu 牛元不执行工具,也不对托管工具服务进行计费。有关具体的路由标志位与计费限制,请参阅 模型路由。

非流式模型供应商 JSON 响应在解码前限制为 16 MiB。超出此大小的响应将作为上游错误失败,并在请求活动记录中保持未完成状态。流式对话对每个 Server-Sent Event (SSE) 最多检查 65,536 字节;除非观察到了有效的终态事件,否则中断或取消的流将保持状态不确定(uncertain)。

对话接口在准入或向模型供应商派发之前会校验常用的生成参数:temperature 范围为 0 到 2,top_p 范围为 0 到 1,存在惩罚(presence_penalty)与频率惩罚(frequency_penalty)范围为 -2 到 2。非空的 max_tokens、max_completion_tokens 和 n 必须为正有符号 64 位整数;非空的 seed 必须为有符号 64 位整数。输出 Token 上限参数只能提供一个非空值。stream 必须为布尔值;非空的 stream_options 必须为对象,且其中的 include_usage(若提供)必须为布尔值。无效的参数值会直接返回清晰的 400 错误,且不会创建操作或尝试记录。省略的可选值与可空值保持原有语义;Niu 牛元不会注入默认采样参数,也不会截断显式传入的值。已配置的原生适配器或计费路由可能会施加更严格的受支持范围限制。

仅当已配置的 OpenAI 兼容路由显式启用了相应能力时,POST /v1/chat/completions 才接受 OpenAI 兼容的函数工具定义、tool_choice 以及值为 json_object 或 json_schema 的 response_format。流式工具调用增量需要单独启用 supports_streaming_tool_calls 标志位。针对已禁用能力的请求会在记录操作或尝试之前返回 501。unsupported_operation_error 错误消息会指明是工具调用、流式工具还是结构化 JSON 不受支持,并给出受支持的替代方案。同时组合使用工具调用与结构化 JSON 仍不受支持;Niu 牛元不会静默移除请求中的这些特性。格式错误的工具定义、选择项和 Schema 会收到 400 错误。

Niu 牛元会将工具定义和结构化输出 Schema 转发给模型供应商,但自身不会执行工具。非流式工具调用响应必须引用已声明的函数并包含 JSON 对象格式的参数。结构化输出响应必须符合自包含的 JSON Schema;json_object 响应必须是 JSON 对象。Schema 编译不支持拉取外部 HTTP 或文件引用,并受限于 文档说明的复杂度限制。模型供应商的实际支持情况必须由实例管理员独立验证。这些特性在原生 Anthropic 或 Bedrock 路由上未启用。按 Token 计费的路由支持纯文本函数工具对话。结构化 JSON 流会先传递临时增量(provisional deltas),并在释放 [DONE] 之前校验组装后的完整内容;无效的终态内容会发出 upstream_invalid_response SSE 错误(不发送 [DONE])并记录失败,同时上报的终态用量仍作为核算证据保留。校验过程在最多 128 个候选项(choices)上保留最多 1 MiB 的内容/拒绝字节。非空的显式模型拒绝(refusal)仍被视为有效拒绝响应。完整的 Responses 兼容性、更广泛的协议一致性以及特定模型供应商的准入认证仍属于后续发布工作。有关终态错误语义、核算与准入限制,请参阅 结构化流式输出契约与当前输入验证。

如果终态模型响应未通过输出校验,Niu 牛元会返回 502 且不投递被拒绝的内容。有效、完整且一致的上报输入/输出 Token 数量仍会记录上游执行完成,并产生锁定的客户费用;因此,投递失败的请求仍可能产生扣费。缺失、无效、不一致或溢出的用量保持未知状态,不会使用估算值替代。HTTP 投递状态与上游执行证据描述的是两个不同的事实。

公开的 Chat、Responses、Embeddings 接口以及控制台对话(Chat)在推理前会以 HTTP 413 拒绝超过 1 MiB(1,048,576 字节)的请求体。无论是否启用请求载荷保留,也无论是否使用不含 Content-Length 头的分块传输(chunked transfer),均适用同一限制。未超过字节上限的请求仍需提供有效的 JSON、受支持的字段、合法的授权以及符合模型特定要求的输入上限。Web 框架层的拒绝可能会返回纯文本而非 API JSON 错误信封。

POST /v1/responses 接受非空字符串 input,以及可选的字符串 instructions、max_output_tokens、temperature、top_p、字符串值的 metadata 和 user。模型路由必须设置 supports_responses = true;Niu 牛元会将模型名称重写为配置的上游模型名称,并将返回的模型名称映射回公开别名。受支持的输出子集包括缓冲或流式响应中的文本消息、推理项(reasoning items)和拒绝内容(refusal content)。用量会将 Responses 的 input_tokens/output_tokens 映射到持久化的 prompt/completion 字段中。

输入数组、图像、音频、工具调用和会话状态不在此子集支持范围内。不受支持的字段或格式错误的结构返回 400;未启用的路由能力会在创建尝试之前返回 501。流式响应的完成需要终态事件和用量证据;初始的 HTTP 200 并不代表生成完成。启用路由计费时,input 加 instructions 必须符合配置的保守 UTF-8 字节上限,且会在派发前预占 max_output_tokens。当前限制详见 模型路由。此适配器子集并不意味着通过了特定模型供应商的一致性认证。

POST /v1/embeddings 接受一个模型别名以及单个非空字符串或由 1–2048 个非空字符串组成的数组。它还可选接受 dimensions(1–65536)、encoding_format(float 或 base64)以及最长 512 字节的 user 字符串。Token ID 数组、嵌套输入、多模态输入、流式传输以及额外未声明字段均会被拒绝。所配置的路由必须使用 openai 或 openrouter 供应商并显式声明支持文本嵌入;自定义维度与 base64 支持需要各自独立的路由显式声明。OpenRouter 的文本嵌入支持不会从对话支持中自动推导。缺失声明或不受支持的供应商会在创建持久化操作和尝试之前返回 501。错误响应会区分基础嵌入、自定义维度和 base64 支持情况;调用方可根据需要改用支持嵌入的模型、省略 dimensions 或改用 float 编码。成功的响应使用公开模型别名,且必须为每个输入项包含一个维度和格式正确的嵌入向量。有关配置与计费边界,请参阅 模型路由。

本契约仅涵盖已实现的 OpenAI 兼容文本嵌入操作。声明的路由标志位属于配置断言,而非一致性测试结果;原生 Anthropic 和 Bedrock 嵌入、特定供应商的一致性测试套件以及其他输入模态均未实现。

每一个获准进入受支持 Niu 牛元推理路由的模型请求都会被自动记录,包含其操作 ID(operation)与尝试 ID(attempt)、公开模型别名、执行状态、阶段耗时、用量可信度、模型供应商上报的 Token 计数以及任何已知的已结算客户费用。请求与响应内容默认单独保留 24 小时,除非通过 x-niu-log-payloads: false 显式禁用;详见 日志中的请求内容。缺失的用量或费用保持未知状态。这是请求活动数据的默认来源,用户无需手动导出或导入网关日志。

GET /api/v1/organizations/{organization}/projects/{project}/requests/{attempt} 可独立于列表分页和筛选条件返回单个请求的元数据。它要求具备该工作空间的读取权限,且当请求不在该工作空间范围内时返回 404。响应使用与请求列表相同的客户安全字段,排除模型供应商采购成本。载荷内容通过独立接口获取。

对于保留的未发送尝试(unsent attempts),可空的 admission_denial 字段会记录经检查的请求速率拒绝原因:RPM 为零时记录 key_request_rate_disabled,正数配额耗尽时记录 key_request_rate_exceeded。其网关 HTTP 429 状态码与捕获的请求密钥名称属于诊断溯源信息,而非上游执行、用量或计费归因。缺失的观测数据保持未知状态;不会根据当前的密钥配置去重构历史记录。此记录范围涵盖持久化的已准备尝试(prepared-attempt)路径,不暗示涵盖计费准入与批处理准入。仅当尝试保持未发送状态时,recorded_failure 和密钥筛选条件才会包含这一已保存的证据。

GET /api/v1/organizations/{organization}/projects/{project}/requests?limit=50 按时间倒序优先返回最新的网关尝试记录。limit 范围为 1 到 100。可选的 from_ms 和 to_ms 限制创建时间(from_ms 为闭区间,to_ms 为开区间);model_alias、key_id 和 status 用于在同一工作空间信息流中进一步筛选。status 的可选值包括 not_sent、may_have_executed、confirmed_completed、confirmed_not_executed、output_withheld、delivery_failed 和 recorded_failure。前四个值用于筛选模型供应商执行状态;output_withheld 选择已记录的被拦截或结果不确定的输出检查记录。recorded_failure 选择已保存的上游失败或未发送的网关准入拒绝证据,不会从未知的用量或执行状态中推断失败。delivery_failed 选择已记录的投递 HTTP 错误(400–599),独立于模型供应商执行状态和客户费用。http_status 接受 100 到 599 之间的精确状态码,或使用 unknown 筛选缺失投递状态的记录,并可与其他筛选条件组合使用。未知(unknown)并不代表成功、失败或未扣费。汇总对象中的 delivery_statuses 会在一致性读取快照中统计所选完整范围内每个已记录状态码及可空未知类别的数量。即使模型供应商已完成执行,请求仍可能因输出被扣留(withheld)而未投递,且仍会产生客户费用。该端点返回 data、可空的 next_cursor,以及在整个所选筛选范围内计算得出的 summary(独立于当前分页)。将上一页最后一条记录的尝试 UUID 作为 after 传入即可继续翻阅更早的匹配条目。分页按最新优先排序;这是一次实时遍历,而非跨页的一致性快照。调用该接口需要工作空间读取权限或实例管理员凭据。每条记录包含 attempt_id、operation_id、可选的 api_key_id 与 key_name、可选的 task_id、可选的 task_evidence、公开的 model 别名及上游供应商上报的可空 provider_model、created_at、dispatched_at、completed_at、duration_ms、execution、可空的 output_guardrail_outcome、usage_confidence、可空的 prompt/completion Token 计数,以及可空的客户费用币种、金额与状态。output_guardrail_outcome 为 null 表示未记录输出检查结果,并不证明已完成投递或内容受保护。Token 数量与货币金额均为精确的十进制字符串。task_evidence 是该工作空间内同一任务 ID 的最新补充执行记录,包含带作用域的执行 ID、来源、记录 ID、覆盖范围声明以及权限/结果对,但不包含导入的调用链跨度(spans)。当操作员打开追踪详情时,请从 /api/v1/organizations/{organization}/projects/{project}/executions/{execution} 获取仅含元数据的跨度与因果链接。未结算或未定价的请求成本可能为未知;它们未出现在成本账本中并不意味着零消费。

请求列表与 CSV 导出支持 sort=time_desc(默认)、time_asc、latency_desc、input_desc 或 output_desc。排序在分页前覆盖所有匹配的请求。已知测量值排在未知值之前;延迟排序使用完整的请求耗时或历史完整持续时间,绝不会将中断的耗时当作完整延迟参与排序。相同值按时间和尝试 ID 决出先后。将 next_cursor 作为 after 翻页时,请保持相同的筛选条件和排序方式。遍历是实时的:在翻页间隙完成测量的请求可能会在排序顺序中发生移动。如需获取所选范围的单语句一致性视图,请使用 CSV 导出。未知的排序值会返回 HTTP 400。客户费用不支持跨不同币种进行排序比较。

GET .../requests/export 使用相同的日期、模型、API 密钥和执行状态筛选条件下载客户安全的 CSV 文件。它通过单条数据库语句读取整个范围,独立于分页的日志页面。该接口需要工作空间读取权限;推理 API 密钥无法执行导出。响应为带有 Cache-Control: no-store 的附件下载。内部标识符、任务记录、请求载荷、凭据以及模型供应商商业数据均被排除在外。未知值保留为空白单元格,并在旁边附带用量与计费状态说明。Token 计数与客户微单位(nanounits)保留精确的十进制数字。类似公式的文本单元格会自动加上单引号前缀以确保电子表格安全。超过 10,000 条请求的导出会返回 413 并提示缩小筛选范围,绝不会静默截断。导出接口拒绝接收分页参数。

范围汇总(summary)会报告匹配的请求总数、包含供应商上报用量的请求数、精确的 prompt/completion Token 总计、具有完整耗时的请求数、平均完整网关耗时、匹配的 P50/P95/P99 延迟分位数(含样本数与边界)、已上报的缓存输入/推理输出类别总和(含已上报和未知的请求计数)、未决和未定价的客户费用计数、按币种汇总的客户费用总额,以及按模型和工作空间 API 密钥划分的用量明细。缺失价格或未结算的尝试保持未知状态,不会转换为零。

charges_by_model 和 charges_by_key 在相同的汇总快照和筛选条件下,按币种分别报告全范围的客户账本金额。金额是以 nanos 为单位的精确十进制字符串;缺失结算会生成 null 币种和金额,并分别统计未决(unresolved)、未定价(unpriced)和未扣费(not-charged)的请求数量。这些计数与已扣费请求数共同构成了每一行的总请求数拆分。密钥标识符仅作为带作用域下钻查询的 API 引用,不可用作界面显示标签。这些明细不包含任何模型供应商采购成本或平台利润。

新准入的请求在工作空间请求信息流中包含一个可空的 timing 对象:dispatch_ms、headers_ms、first_output_ms、total_ms、complete 和 http_status。各时间偏移量使用自请求处理开始的单调网关时钟,独立于载荷捕获。首次输出时间(first_output_ms)从流式对话(Chat)产生第一个有意义的事件开始测量,包括文本、推理思考(reasoning)、拒绝(refusal)或工具调用输出;仅含角色(role-only)的事件、保活心跳(keepalives)和用量记录不计入首次输出。非流式请求的 first_output_ms 保持未知。

日志界面在同一时间轴比例尺上绘制准备阶段、首次输出等待和输出流持续时间。准备阶段包括参数校验与准入检查。等待阶段包括网络传输与上游处理时间;在没有上游追踪跨度(spans)的情况下,Niu 牛元无法将这两者拆分。输出持续时间包含内容投递和终态处理,因此每秒 Token 数(tokens per second)描述的是观测到的输出流速率,而非纯粹的模型计算速度。中断的响应保留未完成的时间区间(包括派发后但在收到响应头之前取消的情况,此时 headers_ms 和 http_status 保持为 null)。进程崩溃或准入确认期间的取消可能会导致阶段耗时不可用。历史旧请求不会进行数据回填。

新的对话补全(Chat Completions)、Responses 和文本嵌入(Embeddings)请求默认在日志中保留内容。若要对单次请求选择退出保留,请发送请求头 x-niu-log-payloads: false。在控制台对话(Chat)界面中,可在发送前关闭输入框设置中的 在日志中保存载荷(Save payloads in Logs)。此设置不会追溯应用于更早之前的请求。

捕获的内容与财务核算记录分开存储,保留期限为 24 小时。请求和响应两侧的捕获上限均为 1 MB;启用内容保留的请求若超出请求捕获上限将被拒绝。流式响应以流式文本形式保留,并对未完成和被截断的响应进行标记。HTTP 请求头与响应头不会被保留。请求对象中的已知凭据字段会被移除,包括 Authorization、Proxy-Authorization、Cookie、Set-Cookie 以及各类 API 密钥请求头名称。提示词(prompt)内部包含的任意机密信息不会自动脱敏。响应捕获会排除机密的模型供应商成本元数据。历史 JSON 和 SSE 响应在读取时也会进行安全清洗。如果格式错误或未完成的结构化响应无法安全序列化,读取接口将返回 HTTP 503 且不返回原始响应体;核算与耗时元数据仍可独立访问。

经授权的工作空间只读成员可以通过 GET /api/v1/organizations/{organization}/projects/{project}/requests/{attempt}/payloads 获取保留的内容。响应中的 data 包含 request、response、content_type、complete、truncated 和 expires_at;若未捕获内容或内容已过期,则返回 null。使用同一路径发起 DELETE 请求删除内容需要工作空间写入权限。删除内容不会删除财务核算记录。持久化的无内容删除标记(tombstone)可防止延迟到达的捕获或重试重新创建已被显式删除的载荷。在捕获完成前执行删除同样会阻止该次尝试的内容被落盘存储。

应用程序或智能体适配器可以在属于同一任务的每一次推理调用上发送相同的可选请求头 X-Niu-Task-ID。对话补全、Responses 和文本嵌入接受 1–200 个可打印 ASCII 字符。Niu 牛元将该值作为不透明的操作元数据存储,绝不会将其转发给模型供应商。未携带此请求头的活动仍会被正常保留,并作为独立的模型请求展示。该请求头仅用于对模型调用进行分组:本地工具执行、校验和任务验收需要独立的适配器事件,无法从网关流量中自动推断。

任务关联仅涵盖由 Niu 牛元处理的模型请求。外部模型调用、智能体工具事件、任务验收以及订阅用量均不在 Niu 牛元的采集范围内。Niu 牛元不提供执行过程或智能体用量的导入 API。

Niu 牛元将 HTTP 端点组织为两个公开路由前缀:

  • 开发者与推理数据面(/v1/* 与 /v1beta/*):模型发现(GET /v1/models)、API 密钥自检(GET /v1/key)、生成记录查询(GET /v1/generations/{id})、文本推理(POST /v1/chat/completions、POST /v1/responses、POST /v1/messages、POST /v1beta/models/{model_action}、POST /v1/embeddings)以及媒体/视频生成(GET /v1/media/capabilities、POST /v1/video/jobs、GET /v1/video/jobs、GET /v1/video/jobs/{id}、POST /v1/video/jobs/{id}/cancel、DELETE /v1/video/jobs/{id}、GET /v1/video/jobs/{id}/results/{kind}、POST /v1/video/jobs/{id}/results/{kind}/refresh)。支持使用工作空间 API 密钥(Authorization: Bearer <niu_api_key>)或搭配 X-Niu-Key-Id: <key_uuid> 的已认证控制台会话进行鉴权。
  • 控制、工作空间、模型供应商与商业管理面(/api/v1/*):身份认证、用户会话、组织、工作空间、统一的工作空间 API 密钥管理(GET /api/v1/workspaces/{workspace}/keys、POST /api/v1/workspaces/{workspace}/keys、GET /api/v1/workspaces/{workspace}/keys/{key}、PATCH /api/v1/workspaces/{workspace}/keys/{key}、DELETE /api/v1/workspaces/{workspace}/keys/{key}、POST /api/v1/workspaces/{workspace}/keys/{key}/rotate)、请求诊断、客户计费、模型供应商目录与报价(Offers)、上游 API 连接、模型路由、定价以及平台设置。鉴权要求因具体操作而异(工作空间成员会话、模型供应商成员身份或平台管理权限)。旧版 /api/v1/* 路径在运行时仍保持支持以确保向后兼容。
  • GET /v1/key 返回当前已认证 API 密钥的名称标签、状态、过期时间、模型访问模式、允许的模型列表、请求速率与 Token 速率限制、并发限制以及客户消费限额(limit_nanos、committed_nanos、remaining_nanos),且不会暴露内部 UUID。
  • GET /v1/generations/{id} 返回调用方工作空间所拥有的单个尝试 ID(attempt ID)的客户安全执行元数据、Token 用量、延迟以及已结算客户费用(total_cost_nanos、currency),同时省略机密的模型供应商成本与内部路由标识符。

实例管理员可以读取工作空间的持久化平台上游核算数据。这些兼容性端点属于采购控制接口,而非客户计费 API。普通工作空间会话与模型供应商成员身份无权访问。

  • GET /api/v1/organizations/{organization}/projects/{project}/budget 返回包含币种、生命周期总额度、预占敞口和已结算现金支出的 data 对象;若未配置预算则返回 null。
  • GET /api/v1/organizations/{organization}/projects/{project}/costs?limit=50 返回已结算条目及可空的 next_cursor。将该 UUID 作为 after 参数传入即可继续翻页;limit 范围为 1 到 100。

这些响应中的所有货币与 Token 值均采用十进制字符串表示,以在浏览器客户端中保留 64 位整数精度。货币金额使用指定币种的十亿分之一(nanos)为单位。每个条目都保留了其尝试 ID 与价格修订版本、独立的 API 等价成本与现金成本、Token 证据,以及用量是否超出预占上限的标志。

分页按尝试 UUID 升序遍历,而非按时间顺序。这是一个实时视图:新结算的条目可能需要重新从头遍历才能看到。未结算的尝试被排除在外;返回空页并不证明零成本。预占敞口仍可在预算接口中查看。订阅费用分摊和容量报告目前尚未包含在内。

即使调用方拥有工作空间读取权限,访问上游成本报告仍需要实例级管理权限。报告端点不会创建价格、结算尝试或启用自动网关定价。面向客户的请求费用、用量(Usage)和计费(Billing)是独立序列化的,绝不会将这些上游采购金额替代为客户费用。

使用管理员令牌向 POST /api/v1/organizations/{organization}/projects/{project}/budget 发送如下请求体:

JSON
{"currency": "USD", "limit_nanos": "100000000000"}

这会为该工作空间创建一个 100 美元(USD)的生命周期上游采购预算。它不会设置客户扣费上限或账单金额。金额必须是有符号 64 位整数范围内的非负十进制整数字符串,不含指数或小数表示法。币种为三位大写字母代码;系统不执行汇率转换。并发创建只有一个请求会成功;若预算已存在,则返回 409 且不会修改其限额、预占或已发生支出。

当前准入行为: 受支持的计费路由会在派发前预占其配置的输入/输出上限;资金不足或缺少匹配币种的预算会阻止发起上游调用。一旦工作空间配置了上游预算,共享路由派发就必须持有受信任的预占记录。没有此类预占的未定价共享请求将被拒绝。经授权且由所有者出资的个人对话(Chat)与视频路由被排除在平台采购核算之外,但其当前的权限与安全护栏(Guardrails)仍然生效。已派发的存量尝试不会被追溯预占。模型供应商计费边界仍需准入验证:低估的边界可能导致超支,并被记录为负债。这并非针对超出边界的上游计费的普遍豁免保证。客户端的“用量(Usage)”页面不会暴露采购预算管理功能。

共享上游连接持久化存储在 PostgreSQL 中,并由实例级管理权限或显式授予的平台管理员角色进行管理:

  • GET /api/v1/vendors 列出所有配置元数据(包括已禁用的配置),不包含凭据密钥。可选的 supplier 参数可按显式的模型供应商业务归属进行筛选。响应为单个不分页的 data 数组,没有静默行数上限;内存占用随列表大小线性增长。
  • POST /api/v1/vendors 使用只写的 api_key 创建上游连接配置。
  • PUT /api/v1/vendors/{id} 使用 expected_revision 更新元数据、启用状态或凭据密钥。
  • GET /api/v1/vendors/{id}/models 按别名顺序排列出该上游连接下的所有模型映射(包括已禁用的映射)。该兼容性端点返回单个不分页的 data 数组,不会在 1,000 行处静默截断。大型列表仍会消耗与其大小成正比的响应内存。
  • POST /api/v1/vendors/{id}/models 在不传修订版本时创建新映射,或使用当前的 expected_revision 更新现有映射。
  • POST /api/v1/vendors/{id}/check 配合 { "alias": "team/fast" } 执行非推理的 GET /models 连通性检查。该检查限制在 5 秒和 2 MiB 以内,拦截重定向与私有网络目标地址,且仅返回状态码以及确切的上游模型 ID 是否出现在供应商目录中。模型供应商的原始响应内容与凭据绝不会被返回。出现在目录列表中并不证明具备推理访问权限或配额;请使用控制台对话(Chat)通过 Niu 牛元测试真实请求。

单个模型供应商可以拥有多个独立配置的凭据,且每个凭据可以绑定多个模型别名。即使多个别名共享同一个上游凭据,工作空间密钥授权仍按每个请求的别名独立生效。有关已验证的更新、禁用、重启与计费行为,请参阅 当前多密钥与多模型验证记录。

更新模型映射时,省略 pricing 会保留其确切的已存储值;显式传入 null 则会将其清空。过期的更新请求会返回 409。响应使用 Cache-Control: no-store。未经显式授予平台管理员权限的普通组织角色与工作空间角色无法管理这些平台资源。有关加密、优先级与引导配置行为,请参阅 模型路由。

GET /v1/video/jobs/{id}/results/video 返回经授权的媒体文件本身,而非私有的上游 URL。已保存的 succeeded 状态并不保证上游结果仍然可供下载。可使用代码仓库中的脚本命令 scripts/verify-video-result.py 读取现有任务、下载其当前结果并使用 FFmpeg 独立解码最终文件。该脚本不会发起提交或刷新请求,并将工作空间密钥保留在环境变量中。有关私有产物、前置条件及确切的验证范围,请参阅 已保存结果验证说明。

持久化视频提交意图(Video Intents)

Section titled “持久化视频提交意图(Video Intents)”

归属于执行者的工作空间 video-intents API 可在显式提交前保存经校验的文生视频请求。PUT /{intent} 保存一个全新的意图标识,GET /{intent} 恢复其内容与原始任务/准备状态,POST /{intent}/submit 则使用 expected_revision 显式提交或重放该意图。集合 GET 接口提供带作用域的元数据索引;DELETE 会清除请求内容,同时保留不可重用的意图标识。当前的密钥授权仅遵循原始密钥的轮换血统(rotation lineage)。读取操作绝不会提交任务、轮询上游或预占资金。

有关请求体结构、执行者隔离、30 天内容保留期、删除语义以及当前的验证限制,请参阅 自动生成的操作 Schema 与 持久化视频意图契约。图像/参考素材输入以及客户出资的视频生成准入验证仍在此已验证子集之外。“生成(Generations)”控制台集成了已保存意图的恢复功能,包括在密钥过期后恢复原始输入、保留的预览以及诊断信息。参考素材的成功提交与完整的共享输出生命周期仍是独立的验证要求。受支持的浏览器工作流详见 生成对话与视频(Generations)。

视频耗时响应包含一个用于结果获取的 result 阶段。其耗时测量上游拉取与有界响应体读取的时间。received 表示网关已获取到媒体字节;但在向客户端投递前会再次检查当前访问权限,因此它并不证明客户端已成功接收。获取失败会记录为 unavailable,并在适配器明确分类时附带上游 HTTP 状态码,否则保持未知。这些记录绝不会创建新的生成任务或产生新的客户费用。获取前的鉴权失败不会创建网络跨度记录。处理器被取消或诊断写入失败可能会导致没有耗时条目被记录。

视频传输耗时条目还会为提交和刷新时的 HTTP 失败暴露可空的 upstream_http_status。历史记录与未分类的跨度保持为 null。此诊断信息绝不会改变已保存的生成状态,也不会证明可以释放费用或预占额度。

视频提交的 HTTP 错误现在会在工作空间请求诊断中保留安全的 upstream_http_error 分类和状态码。创建响应仍返回 202 及 submission_unknown;这并不证明上游未执行、不会释放已持有的客户负债,也不会授权发起另一次新提交。幂等重放会恢复相同的任务引用。详见 自动生成的创建契约。

GET /api/v1/organizations/{organization}/projects/{project}/requests 及其 /export CSV 导出端点接受可选的 operation_id(UUID)参数。该筛选条件会选出已授权工作空间内属于该操作(operation)的所有执行尝试(attempts);列表汇总(summary)同样应用该筛选条件。未知的操作 ID 或属于其他工作空间的操作 ID 将返回空匹配结果。无效的 UUID 语法返回 400。其他筛选条件可与之组合使用,且现有的分页与导出上限仍然生效。

请使用请求元数据返回的 operation_id 进行关联分析;切勿将内部标识符用作产品界面的显示标签。JavaScript SDK 在 listGatewayActivity 和 exportGatewayActivity 中将该参数暴露为 operationId。此只读筛选条件不会触发重试。可空的 retry 元数据提供了每次尝试的序号(ordinal)、前驱尝试(predecessor)、最大尝试次数以及策略修订版本。

客户价目表发布支持可选的 minimum_charge_nanos 字段,该字段为有符号 64 位整数范围内的精确非负十进制字符串。新价目表默认值为零;替换现有的非零最低消费金额需要显式传入新值,传入 "0" 则会在未来的请求中禁用最低消费。null 与格式错误的金额会被拒绝。

对于已知用量的已完成请求,其费用取四舍五入后的 Token 费用与该最低消费金额中的较大值。准入阶段同样预占 Token 上限费用与最低消费金额中的较大值(即使 Token 费率为零也是如此)。用量未知的请求保持未决状态;客户端断开连接不会授权按最低消费扣费或释放未决预占。存量历史记录不会重新计价,且此字段不会配置模型供应商成本或视频生成费用。账单明细行与模型价格查询接口会相应暴露锁定或当前的最低消费金额。内部余额退款上限仍受原始扣费金额约束,仅恢复一次退还的密钥可用额度,并保留历史账单定价。SDK 使用相同的 minimum_charge_nanos 字段。详见 契约与实际验证记录。

当前版本的网关在完成传输状态数据库迁移后,成功恢复了一个此前生成的个人视频任务,查询了其真实的上游引用,并在重启后保留了同一个成功的任务记录。下载的字节流与原始产物的 SHA-256 完全匹配,并可独立解码为 H.264 视频。整个过程未创建新的生成任务,也未产生客户费用。这验证了该结果恢复路径,但不代表客户出资的视频结算验证。详见 已记录的恢复验证证据。

客户价目表发布现在接受 request_fee_nanos 作为精确的非负整数字符串。对于已知用量的已完成请求,其最终扣费取“四舍五入后的 Token 费用加上该固定单次费用”与 minimum_charge_nanos 之间的较大值。准入阶段使用相同的公式预占额度;被拒绝或未决的请求不会凭空产生固定费用。历史价目表版本保持锁定不变。替换非零的固定费用需要显式传入新值,传入 "0" 则将其禁用。SDK 使用相同的字段名称。详见 计费规则与受支持边界。

针对当前输入的固定费用验证现已涵盖缓冲与流式 Responses、共享同一账户并发运行的 Chat/Responses/Embeddings,以及有界的幂等内部退款。独立的供应商响应算术校验与数据库账本读取结果完全一致;服务重启后仍保留了费用记录与已恢复的额度。详见 协议与退款验证证据。

纯固定费用定价还在两个网关实例与两个工作空间并发争用仅够支付一次请求的企业授信额度场景下进行了验证:最终一个请求完成、一个返回 HTTP 402,且账本仅产生一笔精确扣款。另一次在流式内容实际输出后触发 SIGKILL 的测试保留了未知用量及其预占记录,而没有凭空产生固定费用扣款或触发重试。详见 并发争用与崩溃验证证据。

在固定费用准入阶段,如果 Token 费用加上固定费用的总额超出了有符号 64 位微单位(nanounits)的表示范围,网关会以 HTTP 400 拒绝请求。数值可表示但可用消费容量不足的请求则返回 HTTP 402。实际 API 请求与独立 SQL 检查证实,这两种情况均未向上游派发请求,也未留下任何资金预占记录;详见 准入边界验证证据。

GET /v1/models 已包含在由路由处理器自动生成的 OpenAPI 契约中。模型的 customer_pricing 字段包含当前已认证工作空间的现行销售价目表(若未定价则为 null)。Token 费率以每百万 Token 的微单位(nanounits)表示;minimum_charge_nanos 和 request_fee_nanos 则是按次计算的对应币种微单位。请将所有金额保持为字符串处理。SDK 在模型价格和账单明细行上均暴露了这两个费用字段。模型发现本身并不保证请求准入或上游可用性。详见 实际作用域价格读取验证。

使用 GET /api/v1/organizations/{organization}/projects/{project}/billing/tariffs/{model}/history 或 SDK 的 getCustomerTariffHistory 方法可读取不可变的客户文本价格历史。响应包含当前修订版本以及带 next_before 游标的最新优先分页;所有货币字段均保持为字符串。跟随游标可继续向后翻页,刷新第一页即可查看新发布的价格。缺失或跨资源的游标返回 409;无权访问的工作空间或未知的模型价目表返回 404。响应排除模型供应商采购价格。详见 契约与实际分页验证证据。

客户价目表历史记录接口允许带作用域的管理端只读角色访问(包括实际鉴权运行中验证的所有者 owner 与只读成员 viewer 角色)。工作空间推理 API 密钥无法读取此管理端点,请改用其获准访问的 /v1/models 价格投影。跨工作空间的历史记录仍以 404 隐藏。前端集成清单 现已将价格发布、当前价格与不可变历史记录一并列出。

缓存输入与固定单次费用组合计费

Section titled “缓存输入与固定单次费用组合计费”

当配置了 cached_prompt_rate 时,系统会分别计算未缓存输入、缓存输入和输出的精确金额,将三者相加后统一向上取整一次;然后再累加 request_fee_nanos,并对合并后的总金额应用 minimum_charge_nanos 下限。缺失必要的缓存用量数据时,请求将保持未决状态;固定费用不会替代缺失的用量证据。所有费率与固定金额均保留其锁定的修订版本。

实际的非零缓存完成请求验证了叠加固定费用以及最低消费高于合并金额的两种场景。已保存的供应商用量与重新打开的数据库记录在费用、账单和退款余额上完全吻合。详见 计费公式与验证范围。

GET /api/v1/providers/{provider}/offers/{offer}/revisions/{revision} 用于读取已知的历史采购报价修订版本。调用方必须具备实例级管理权限或是该模型供应商的活跃成员;客户组织所有者身份不授予此访问权限。模型供应商、报价(offer)与修订版本(revision)必须相互匹配。缺失或无权访问的报价返回 404。JavaScript SDK 提供了 getSupplierOfferRevision 方法。

文本费率保持为精确字符串,包含可空的缓存输入定价。媒体报价修订版本的文本价格字段为 null,并使用独立的媒体费率卡(rate-card)API。读取报价不会激活或验证该报价。请务必将采购信息隔离在客户工作空间界面之外。由路由处理器生成的 OpenAPI 现已记录了响应变体与鉴权边界。当前的 HTTP 读取测试与四个已保存的文本修订版本完全匹配;活跃模型供应商只读成员访问、客户企业角色拒绝以及成员资格吊销均已针对数据库记录进行了独立核验。媒体报价读取仍有待验证。

GET /api/v1/providers/{provider}/offers/{offer}/revisions 可在不预先获知修订版本 ID 的情况下列出历史采购报价。该接口适用相同的模型供应商成员身份或平台管理权限要求。使用 limit(1–100,默认 50),并在 has_more 为 true 时将 next_before 作为 before 传入。每个条目增加了 is_current 标志,且响应中包含 current_revision。未知或跨资源的游标返回 409,无权访问的模型供应商或报价标识返回 404。

SDK 提供了 listSupplierOfferHistory 方法。在集成前请先阅读 分页与保密性契约。这些数据属于平台采购价格,而非客户计费数据。

平台管理员可以读取或更新 /api/v1/vendors/{vendor}/request-rate-limit 并读取其 /history 历史记录。PUT 请求需要传入 requests_per_minute(显式传入 null 表示无限制,传入 0 表示停止派发)以及精确的字符串 expected_revision。该限制独立于客户密钥的 RPM 限制,并在使用同一已保存凭据的所有网关实例之间共享。历史记录接口支持 before_revision 和 limit 参数。

本地派发限流拒绝会返回 HTTP 429、upstream_request_rate_exceeded 以及保守的 Retry-After: 60 响应头,且不会向上游发送请求。SDK 提供了 getVendorRequestRateLimit、setVendorRequestRateLimit 和 listVendorRequestRateLimitHistory 方法。详见 派发语义与验证边界。

平台管理员可以读取 GET /api/v1/vendors/{vendor}/cooldown 或使用 SDK 的 getVendorCooldown 方法。响应会报告 policy_revision、failure_threshold、window_seconds、cooldown_seconds、active、可空的 cooldown_until 以及 qualifying_failures。企业作用域的管理员无权读取此状态。

在 60 秒滚动窗口内若出现 3 次新的、符合条件的规范 OpenRouter 文本认证拒绝,该凭据将在接下来的 60 秒内暂停被新请求选中。后续符合条件的在途失败可能会延长冷却截止时间。超时与执行状态不确定的请求绝不计入冷却阈值。直接选择处于冷却期的路由会返回 503 upstream_credential_cooldown;没有任何可用映射的路由池会返回 503 route_pool_unavailable。已锁定路由的在途请求继续执行。冷却状态在服务重启和凭据编辑后依然保留;冷却到期后会自动恢复候选资格,无需发起上游探测或由管理员重新发布。此固定策略不提供写入端点。详见 冷却策略与验证边界。

现有的 provider_model 字段现在会保留经校验的视频状态查询所显式返回的模型名称。缺失的模型供应商模型字段保持未知状态;Niu 牛元不会用配置的映射名称去替代。已完成的存量任务可以通过一次上报了该字段的授权刷新操作获得此模型归因,而无需重新发起生成。仅读取日志(Logs)不会向上游发起查询。详见 模型归因与保留边界。

新的视频提交会通过现有的带作用域载荷读取/删除 API 保留经检查的 Niu 牛元请求体与 Niu 牛元创建响应体,保留时间最长为 24 小时。发送 x-niu-log-payloads: false 可选择退出保留。已保存意图(saved-intent)的提交会捕获经检查的视频请求内容,而非仅含修订版本的提交信封。幂等重放绝不会重新创建捕获记录。这些载荷是 Niu 牛元 API 的请求与响应体,而非原始上游传输报文或生成的媒体文件;完整捕获到 202 响应并不代表视频生成已完成。

有关大小上限、鉴权与保留语义,请参阅 视频请求载荷。

HTTP 401 响应并不能普遍证明模型供应商没有执行任何计算工作。受管文本请求在准入时会锁定经审查的规范 OpenRouter 未执行策略;使用相同适配器的自定义端点以及未绑定该策略的旧请求仍保留执行不确定性及其适用的资金预占。客户诊断信息会将 HTTP 失败与执行状态、扣费状态分开保存。切勿将每一个 401 响应都视为已退款或允许直接重试。

有关已实现的边界与实际验证,请参阅 符合条件的未执行策略。

网关在开始监听端口前,会检查每一个已保留的模型供应商推理凭据与素材管理凭据修订版本。若部署加密密钥缺失或不兼容,网关将采取故障关闭(fail closed)策略拒绝启动。已吊销的素材凭据在被显式擦除前仍会接受检查;启动过程不会删除或重新加密它们。请恢复匹配的部署密钥,而不要通过擦除数据库数据来绕过诊断检查。详见 启动校验及其限制。

GET /api/v1/providers/{provider}/settlements 提供了超出模型供应商控制台最近 100 条付款记录上限的完整结算历史。平台管理员或该模型供应商的活跃成员均可读取。支持使用 limit(1–100)、before、currency、from_ms(闭区间)和 to_ms(开区间)参数;在跟随 next_cursor 翻页直至为 null 的过程中,请保持筛选条件不变。时间边界为 Unix 毫秒时间戳。SDK 提供了支持 fromMs 和 toMs 查询属性的 listSupplierSettlements 方法。

所有金额均为精确的十进制字符串。返回行仅包含付款记录元数据,不包含客户信息与具体请求详情。读取结算历史不会登记付款或转移资金。详见 契约与验证边界。

优雅停机(Graceful shutdown)现在会在 HTTP 连接与财务写入器排空后,额外等待最多 10 秒以完成已注册的请求耗时与内容写入。超出该时间窗口的数据库停滞会发出 request_diagnostics_shutdown_timeout 事件;强制终止进程或存储层故障仍可能导致诊断数据缺失。诊断内容缺失并不代表获准重试状态不确定的上游操作。详见 实际停机验证与限制。

GET /api/v1/organizations/{organization}/projects/{project}/billing/invoices 支持翻阅超出概览页最近 100 张账单上限的全部历史账单。使用 limit(1–100)、before、currency、from_ms 和 to_ms 参数,并跟随 next_cursor 翻页直至为 null。这些时间筛选条件描述的是账单的创建时间;而每张返回账单中的 from_ms / to_ms 仍然描述其计费的用量时间区间。SDK 提供了支持共享 LedgerHistoryQuery(fromMs、toMs)的 listCustomerInvoices 方法。

该端点强制检查工作空间读取权限范围,且仅返回客户侧金额。已入账的余额扣款即使使用了已批准的授信额度,也会结清对应账单,不会变成另一笔未付账单欠款。读取历史记录不会创建付款。详见 契约与 152 张账单实际验证记录。

当响应体在到达终态或显式上游失败处理之前被断开时,请求详情可能会报告 failure.kind: response_stream_cancelled 且 upstream_http_status 为 null。这并不能指明是谁取消了投递,也不能证明上游执行没有发生。此时响应头可能已经是 HTTP 200,而耗时与内容捕获仍处于未完成状态。

未知的用量、资金预占以及密钥并发占用均会保留;流取消不会触发自动重试或凭据冷却。已完成的流和已知的上游错误则保留其各自的结果状态。详见 实际取消、完成与超时验证记录。

平台管理员可以使用 GET /api/v1/providers/{provider}/earnings 翻阅超出管理概览页近期收益预览范围的完整记录。SDK 提供了 listSupplierEarnings 方法;返回的精确金额仍为平台对模型供应商的应付负债。模型供应商成员身份不授予此请求级对账访问权限。内部候选路由选择 ID(selection IDs)切勿出现在产品界面中。现有的结算写入接口仍会重新校验未付选择项并要求提供已确认的付款证据。非空分页与完整的模型供应商对账仍有待验证。

具有显式权限的平台管理员可以通过 GET /api/v1/pricing/targets 发现已命名的企业/工作空间定价目标,随后通过 GET /api/v1/pricing/organizations/{organization}/workspaces/{project}/tariffs 读取现行销售价格。两个接口均使用 after、limit(1–100)和 next_after 进行分页。在价目表路由后追加 /{model}/history 即可读取不可变的价格历史记录(使用 before、limit、next_before)。这些读取接口不包含客户余额、用量、账单对账单、请求内容或模型供应商采购信息。客户作用域的计费访问权限保持独立。对应的 SDK 方法为 listPlatformPricingTargets、listPlatformCustomerTariffs 和 getPlatformCustomerTariffHistory。

已记录的准备阶段策略拒绝会返回 HTTP 403 及 error.type: "guardrail_denied",表示请求在派发给模型之前即被拦截。响应不会暴露命中的输入片段或具体规则。请读取经授权的准备阶段诊断信息以了解记录的拒绝原因;切勿将所有 403 响应都归类为安全护栏拦截。管理权限失败保留其独立的错误类型。

派发后的缓冲输出扣留(withholding)返回 HTTP 403 及 error.type: "guardrail_output_withheld"。即使输出内容未被投递,生成费用仍可能照常产生。请检查经授权的请求安全护栏诊断信息以获取已保存的结果状态;切勿自动重试该操作。

POST /v1beta/models/{alias}:generateContent 可用于已显式启用的静态或受管 gemini 路由。请对模型别名(包括其中的斜杠 /)进行 URL 编码,并使用 Niu 牛元工作空间密钥进行身份认证。请求需提供文本类型的 contents 以及有界的 generationConfig.maxOutputTokens。原生工具调用、媒体输入、缓存资源、思考配置(thinking configuration)以及流式传输均不受支持,并在派发前即被拒绝。现有的预付费定价、权限控制与密钥限额仍然生效。

SDK 使用以 /v1 结尾的基础 URL 暴露了 client.generateContent(alias, body) 方法。自动生成的契约文档 列出了确切受支持的字段。实际的异常路径、输入脱敏、保留的上游拒绝以及服务重启均已通过验证;成功的 Google 生成调用、输出处理与已结算计费仍有待验证。模型供应商凭据支持 adapter: "gemini";模型映射需要配置 capabilities.supports_generate_content: true。模型发现与连通性检查使用原生 Google 认证方式及有界目录读取。详见 实现与验证边界。

POST /v1/messages 在已显式启用的 OpenRouter 或 Anthropic 模型映射上支持有界非流式文本生成。对于受管映射,请设置 capabilities.supports_messages: true。Anthropic 映射可以通过相同的模型供应商配置 API 保存保守的路由采购价格;客户销售价目表仍与之保持分离。缺失的用量保持未知状态。不受支持的推理思考费率(包括显式的零费率)会在派发前被拒绝。执行状态不确定的上游拒绝会保留其计费预占以供后续核对。

实际的配置保存、预付费余额不足拒绝、价格类别拒绝、输出上限限制以及跨重启的拒绝状态持久化均已通过验证。成功的直连 Anthropic 结算仍有待验证。详见 原生协议支持范围。

未结清的余额预占(Open Balance Reservations)

Section titled “未结清的余额预占(Open Balance Reservations)”

企业所有者/管理员以及实例管理员可以通过 GET /api/v1/organizations/{organization}/billing/reservations 检查未结清的资金冻结(holds)。支持使用 limit(1–100)、可选的 currency 以及取自 next_before 的 before 参数。已释放的预占会从结果列表中消失,但仍可作为有效的分页游标。响应包含工作空间/密钥名称、模型别名、当前执行/用量状态,以及精确的客户预占金额与未结清金额。内部标识符仅作为关联链接使用,不可用作界面显示标签。响应排除模型供应商成本与上游凭据。

这是一个只读诊断接口,而非资金释放或重试操作。未知的执行或用量状态保持为未知。不同分页之间属于独立的读取观测。已完成但用量不完整的响应保持为 usage_unknown;已知用量但正在等待财务核算恢复的响应则报告为 settlement_pending。实际调用已验证这两种状态在服务重启后的持久性,以及仅释放可恢复冻结款项的行为。SDK 提供了 listCustomerBalanceReservations 方法;详见 支持范围与实际验证记录。

当原始请求截止时间(deadline)在准备阶段或正式派发前到期时,对话(Chat)与 Responses 的路由池准入可能会返回 HTTP 504 及 error.type: "request_deadline_exceeded"。该次尝试并未发送到上游。一次重试操作可能已经包含了早先的上游拒绝记录;在关联到请求诊断信息时,请保留返回的任何 x-niu-operation-id 和 x-niu-attempt-id 响应头。

请在界面中将其展示为请求超时,而非数据库可用性故障。此错误分类并不授权对状态不确定的尝试或已开始返回的流进行重放。在决定是否发起新操作之前,请先检查已保存的请求状态。其他 HTTP 504 错误并不会仅仅因为状态码相同而自动继承这一“未执行”保证。

详见 有界重试与截止时间契约。

返回 HTTP 409 及 guardrail_admission_conflict 表示在当前工作空间/密钥策略下,先前检查通过的策略已不再允许派发该请求。被拒绝的尝试并未发送到上游。付费准入仍会保留一条未发送的尝试记录及其安全的拒绝审计信息,同时释放客户资金预占,且不会产生客户扣费。新请求必须在当前最新策略下重新接受检查。

Messages 接口保留其原生错误信封结构;请读取 x-niu-error-code 响应头以获取 Niu 牛元的错误分类。通用冲突与未知的数据库故障保留其各自独立的含义。详见 策略竞态行为与验证证据。“生成(Generations)”控制台集成了已保存视频意图的恢复功能,包括在密钥过期后恢复原始输入、保留的预览以及诊断信息。参考素材的成功提交与完整的共享输出生命周期仍是独立的验证要求。受支持的浏览器工作流详见 生成对话与视频(Generations)。