API reference
The inference API is served by the gateway; the console API (keys, usage, billing) is what the console itself uses and is documented for automation.
Inference API
https://gridport.ai/v1https://gridport.aiThe OpenAI SDKs expect the base URL to include /v1. The Anthropic SDK adds /v1/messages itself, so it takes the gateway root without /v1. Paths in the table below are relative to the gateway root. Authenticate with Authorization: Bearer sk-tf-….
Unknown and unsupported parameters
A parameter the platform does not recognise is dropped before the call and named in the x-tf-ignored-params header and in tf.ignored_params. Reasoning controls (reasoning_effort, an Anthropic thinking block) on a model without adjustable reasoning are handled the same way. A parameter that asks for a capability the model does not declare — tools, response_format json_object or json_schema, image input, stream — is refused with 400 unsupported_parameter and the parameter name in param.
Model name modifiers
A client that can only change the model name can still ask for a thinking budget or a temperature, by appending modifiers to the name. The catalogue name, the price and the limits are unchanged; only the request body is. A modifier we do not recognise is refused, so a typo never passes silently.
deepseek-ai/DeepSeek-V4-Flash@effort:high # low | medium | high | minimal | none …@thinking:on …@thinking:off …@thinking:2048 # on = medium; a budget maps to low (≤4096), medium (≤16384) or high …@temperature:0 …@topp:0.9 …@2026-04-24@effort:low # a pinned version still works, and combines
The request log records the name you sent, including the modifiers, while the model, price and rate limit are the catalogue entry's. Reasoning controls — @effort, @thinking, the reasoning_effort parameter and an Anthropic thinking block — apply to models whose page lists adjustable reasoning; on any other model they are ignored and named in x-tf-ignored-params and tf.ignored_params, never refused.
Response headers
x-request-id: req_01J… # quote this in support requests and find it in the request log x-ratelimit-limit-requests: 600 x-ratelimit-remaining-requests: 597 retry-after: 12 # on 429 and on a retryable 5xx x-tf-default-max-output-tokens: 4096 # max_tokens was not set; this limit was applied x-tf-max-output-tokens: 32768 # max_tokens was above the model's ceiling and was lowered to it x-tf-model-alias: @cs-default # the request named this model alias x-tf-model-redirect: … # a retired model was served by its replacement; names the model you asked for Deprecation: @1788220800 # the model is deprecated: when it was announced (RFC 9745) Sunset: Thu, 03 Dec 2026 00:00:00 GMT # …and when it retires (RFC 8594) Link: <https://…>; rel="deprecation" # the deprecation notice, when there is one
Deprecation, Sunset and Link come with every response from a deprecated model until it retires; x-tf-model-alias with every request made through an alias. Deprecation and retirement
Streaming
Set stream: true. Chunks are SSE data: lines in the OpenAI chunk shape and the stream ends with data: [DONE]. A streamed response carries usage (with cost) in its last data chunk only when the request sets stream_options.include_usage; without it no usage chunk is sent, as with OpenAI. The request log has the usage either way.
If an upstream fails after the first byte, the stream ends with an error event and a finish_reason of "error"; you are billed only for tokens delivered. Streaming
Console API
Base URL: /api. Cookie session with an X-Requested-With: XMLHttpRequest header on writes. Money is returned as decimal strings in USD. Scripts and CI use an access token instead of a session. Access tokens
GET /me session, organizations, projects
GET /projects/{id}/api-keys POST to create (secret returned once)
GET /projects/{id}/requests request log, cursor paginated; /requests/{id} for one
GET /projects/{id}/usage?from&to&granularity&groupBy&format=csv
GET /orgs/{id}/usage the whole company: groupBy=project|member|key|model|user|tag:<key>
GET /orgs/{id}/billing/balance ledger, pending, buckets, thresholds
GET /orgs/{id}/billing/ledger-summary the ledger, usage merged per hour × project × model
GET /orgs/{id}/billing/transactions.csv ?view=summary (merged) or detail (every entry)
PATCH /orgs/{id}/billing/alerts { lowThresholdUsd, criticalThresholdUsd }
GET /orgs/{id}/billing/statements/{YYYY-MM} by project and by model; .pdf for the PDF
POST /orgs/{id}/billing/top-ups { amountUsd } → checkout_url
GET /orgs/{id}/billing/payments payments and receipts
GET /me/notifications POST …/read-all, …/{id}/readMembers, roles and project access
Each member has one organization role. Owners hold every permission; admins run projects, API keys, members and webhooks but do not top up or change organization settings; billing admins handle payments, budgets, balance alerts, company-wide usage and billing evidence; developers create and use API keys and read request logs; viewers read; auditors read usage, billing, request logs and the audit log, and export billing evidence.
A member can also hold a role in a project — project admin, developer or viewer — which only adds to the organization role inside that project: a project admin manages the project’s settings, members, aliases, rate limits, budget and every key in it. Project members are managed under Settings → Project members, and the access mode under Settings → Members. A personal organization can be converted into a company organization in its settings, with a new name and URL. When project access is restricted, developers and viewers reach only the projects they are members of, and the project, key and budget lists show them only those; owners, admins, billing admins and auditors see every project.
GET /projects/{id}/members the project's members and roles
POST /projects/{id}/members { userId, role: admin | developer | viewer }
PATCH /projects/{id}/members/{userId} { role }; DELETE removes the member from the project
PUT /orgs/{id}/project-access { mode: open | restricted }
PUT /orgs/{id}/allowed-models { models: [...] }: the organization's model list; [] allows every model
GET /projects/{id}/model-aliases and /orgs/{id}/model-aliases; POST, PATCH /{id}, DELETE /{id}
PATCH /projects/{id}/limits { rpm, tpm }: the project's rate limits (null for none)Each of these changes is recorded in the organization’s audit log. Finance roles · The organization’s model list
Key self-check
GET /v1/key Authorization: Bearer sk-tf-…
Use an inference key to inspect only that key: name, prefix, expiry, allowed models, effective shared-inference limits and its own budgets. Organization balance, other keys and payment details are excluded. Console access tokens and worker tokens are not accepted.
Amounts are exact USD strings; null limits mean unlimited and zero remains zero. usage reports settled metered cost, not wallet debits or immediately spendable balance. It excludes unsettled usage; subscription funding, credit refunds and organization rounding are not allocated to this figure. Month boundaries use UTC. as_of, snapshot_id, latest_settled_usage_at and unsettled_records describe the snapshot; the latest event timestamp is not a guarantee that every earlier event has arrived.
Fresh statistics were sampled within the last 60 seconds; stale values keep their original as_of for at most five minutes. Unknown or previous-month statistics are null. When the key cannot be checked right now the call returns 503 with Retry-After; an invalid key returns 401. Changes made in the console, such as disabling the key, show here within 15 seconds. The self-check is not billed and has its own limits of 12,000 requests per minute per IP and per key; poll sparingly and honour Retry-After.