Skip to content

Commit

Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens

models.g1t.sh/anthropic answers a workspace access token with the models scope, charges each request at list price (markup 0) from included usage and AI credit, refuses one it cannot pay for, and only counts requests on the workspace's own key. Logs page, REST, MCP and a guide. Conflict: Op::ALL is 219 (the rulesets and the gateway's operation). The docs' OpenAPI copy is regenerated.

syntaqxcommitted Parents5a1473e36a518aBrowse files
51 files+369−120/51 viewed
+1−0
269269 token_id: "tok_1".to_owned(),
270270 scopes: scopes.map(|scopes| scopes.iter().map(|scope| scope.as_str().to_owned()).collect()),
271271 legacy,
272+ name: None,
272273 })),
273274 ..User::default()
274275 }
+35−3
412412 })
413413 }
414414 Op::GetBillingDetails => shaped(g1t_kit::call(billing, "billing_details", &account).await?, &details_json),
415+ Op::ListGatewayRequests => {
416+ let limit = match &input["limit"] {
417+ Value::Null => None,
418+ Value::Number(number) => number.as_u64(),
419+ Value::String(digits) => digits.trim().parse().ok(),
420+ _ => Some(0),
421+ };
422+ if limit.is_some_and(|limit| !(1..=200).contains(&limit)) {
423+ return failed(FailureCode::Invalid, "limit is a number from 1 to 200.");
424+ }
425+ let before = input["before"].as_str().map(str::trim).filter(|id| !id.is_empty());
426+ let page: Outcome<Value> = g1t_kit::call(
427+ billing,
428+ "gateway_requests",
429+ &json!({ "workspace": workspace, "viewer": viewer, "limit": limit, "before": before }),
430+ )
431+ .await?;
432+ shaped(page, &snake)
433+ }
415434 _ => failed(FailureCode::Invalid, "Not a billing operation."),
416435 }
417436 }
559578 assert!(shown.get("invoices").is_none() && shown.get("upcoming").is_none());
560579 }
561580
562− const OPS: [Op; 7] =
563− [Op::GetUsage, Op::GetBudget, Op::SetBudget, Op::GetAiCredit, Op::BuyAiCredit, Op::ListInvoices, Op::GetBillingDetails];
581+ const OPS: [Op; 8] = [
582+ Op::GetUsage,
583+ Op::GetBudget,
584+ Op::SetBudget,
585+ Op::GetAiCredit,
586+ Op::BuyAiCredit,
587+ Op::ListInvoices,
588+ Op::GetBillingDetails,
589+ Op::ListGatewayRequests,
590+ ];
564591
565592 /// Billing belongs to a workspace, needs someone signed in, and is one
566593 /// MCP tool whose writes no preset but full access reaches.
579606 token_id: "tok_1".into(),
580607 scopes: preset.scopes().map(|scopes| scopes.iter().map(|scope| scope.as_str().to_owned()).collect()),
581608 legacy: false,
609+ name: None,
582610 };
583611 for preset in [Preset::ReadOnly, Preset::Agent] {
584612 let access = token(preset);
585613 let seen: Vec<&str> = tool.visible(&Gate::Token(&access)).iter().map(|action| action.name).collect();
586− assert_eq!(seen, ["usage", "budget", "ai_credit", "invoices", "billing_details"], "{}", preset.as_str());
614+ assert_eq!(seen, ["usage", "budget", "ai_credit", "invoices", "billing_details", "gateway_requests"], "{}", preset.as_str());
587615 }
616+ // The AI Gateway's log needs models:read, and nothing of billing's.
617+ let models = TokenAccess { scopes: Some(vec!["models:read".into()]), ..token(Preset::Ci) };
618+ let seen: Vec<&str> = tool.visible(&Gate::Token(&models)).iter().map(|action| action.name).collect();
619+ assert_eq!(seen, ["gateway_requests"]);
588620 let full = TokenAccess::full();
589621 assert_eq!(tool.visible(&Gate::Token(&full)).len(), OPS.len());
590622 }
+3−1
6464 ),
6565 (
6666 "Billing",
67− "A workspace's usage, its budget, its AI credit and its invoices. Members read them; owners change the budget and buy credit, as people. g1t's agents never change billing.",
67+ "A workspace's usage, its budget, its AI credit, its invoices and its AI Gateway requests. Members read them; owners change the budget and buy credit, as people. g1t's agents never change billing.",
6868 &[
6969 Op::GetUsage,
7070 Op::GetBudget,
7373 Op::BuyAiCredit,
7474 Op::ListInvoices,
7575 Op::GetBillingDetails,
76+ Op::ListGatewayRequests,
7677 ],
7778 ),
7879 (
533534 Op::BuyAiCredit => "Buy AI credit",
534535 Op::ListInvoices => "List a workspace's invoices",
535536 Op::GetBillingDetails => "Get a workspace's billing details",
537+ Op::ListGatewayRequests => "List a workspace's AI Gateway requests",
536538 Op::PinProject => "Pin a project",
537539 Op::UnpinProject => "Unpin a project",
538540 Op::ReorderPinnedProjects => "Reorder your pinned projects",
+18−2
259259 BuyAiCredit,
260260 ListInvoices,
261261 GetBillingDetails,
262+ ListGatewayRequests,
262263 RequestReviewers,
263264 RemoveRequestedReviewers,
264265 GetCodeownersErrors,
628629 }
629630
630631 impl Op {
631− pub const ALL: [Op; 218] = [
632+ pub const ALL: [Op; 219] = [
632633 Op::Whoami,
633634 Op::GetWorkspace,
634635 Op::CreateWorkspace,
800801 Op::BuyAiCredit,
801802 Op::ListInvoices,
802803 Op::GetBillingDetails,
804+ Op::ListGatewayRequests,
803805 Op::RequestReviewers,
804806 Op::RemoveRequestedReviewers,
805807 Op::GetCodeownersErrors,
10271029 Op::BuyAiCredit => "buy_ai_credit",
10281030 Op::ListInvoices => "list_invoices",
10291031 Op::GetBillingDetails => "get_billing_details",
1032+ Op::ListGatewayRequests => "list_gateway_requests",
10301033 Op::RequestReviewers => "request_reviewers",
10311034 Op::RemoveRequestedReviewers => "remove_requested_reviewers",
10321035 Op::GetCodeownersErrors => "get_codeowners_errors",
15131516 Op::GetBillingDetails => {
15141517 "Who a workspace's invoices are made out to: the billing `email`, `name`, `address`, tax ID (`tax_id_type`, `tax_id`), `po_number` and the invoices' `language`, with the default `payment_method` as far as it is safe to show (its kind, brand, last four digits and expiry). `customer` is false until the workspace has been set up to pay. Tax is worked out from the address: `tax_location` says whether it is enough for that (a country, and in the US a ZIP code), `tax_address_needed_at` is set while g1t is holding a charge for want of one, `tax_id_status` is Stripe's check of the tax ID (`pending`, `verified`, `unverified` or `unavailable`), and `tax_exempt` is `none`, `exempt` or `reverse`. Members of the workspace only."
15151518 }
1519+ Op::ListGatewayRequests => {
1520+ "A workspace's recent AI Gateway requests, newest first: each with its `id`, `created_at`, `model`, the access token that sent it (`token_id`, `token_name`), its tokens by kind (`input`, `output`, `cache_read`, `cache_write`), what they cost at the model's price (`cost_micros`) and what the workspace was charged (`charged_micros`, before included usage and AI credit paid for it; 0 on the workspace's own provider key, `own_key`), the HTTP `status` it was answered with, whether it was `streamed`, `duration_ms`, and `error` for one that was refused or failed. Prompts and answers are never kept. `limit` is how many, 50 unless given and 200 at most; pass `next` from one page as `before` for the next. Requests are kept `retention_days` (30). Members of the workspace only."
1521+ }
15161522 Op::ListUserTeams => {
15171523 "The teams someone is in within a workspace, as list_teams describes them, leaving out secret teams you cannot see. Members of the workspace only."
15181524 }
27762782 Op::GetBudget | Op::GetAiCredit | Op::ListInvoices | Op::GetBillingDetails => {
27772783 object(json!({ "workspace": workspace_schema() }), &["workspace"])
27782784 }
2785+ Op::ListGatewayRequests => object(
2786+ json!({
2787+ "workspace": workspace_schema(),
2788+ "limit": { "type": "integer", "minimum": 1, "maximum": 200, "description": "How many requests, newest first. 50 if not given." },
2789+ "before": { "type": "string", "description": "Only requests older than this one: the `next` of the page before." },
2790+ }),
2791+ &["workspace"],
2792+ ),
27792793 Op::SetBudget => object(
27802794 json!({
27812795 "workspace": workspace_schema(),
29632977 | Op::BuyAiCredit
29642978 | Op::ListInvoices
29652979 | Op::GetBillingDetails
2980+ | Op::ListGatewayRequests
29662981 )
29672982 }
29682983
47594774 | Op::GetAiCredit
47604775 | Op::BuyAiCredit
47614776 | Op::ListInvoices
4762− | Op::GetBillingDetails => crate::billing::run(self, services, viewer, input).await,
4777+ | Op::GetBillingDetails
4778+ | Op::ListGatewayRequests => crate::billing::run(self, services, viewer, input).await,
47634779 Op::ListUserTeams => {
47644780 pass(
47654781 identity,
+51−0
59615961 },
59625962 "notes": "Open `url` in a browser to pay. Nothing is charged until the payment is made there; the credit then shows in get_ai_credit. An amount outside `min_cents` to `max_cents`, or not in whole dollars, is refused with `invalid`; a workspace that cannot buy credit (see `can_buy`) gets `conflict` or `payment_required`."
59635963 },
5964+ "list_gateway_requests": {
5965+ "params": {
5966+ "workspace": "flagon-io"
5967+ },
5968+ "query": {
5969+ "limit": 2
5970+ },
5971+ "response": {
5972+ "requests": [
5973+ {
5974+ "id": "gw_5f0c2a9e7b1d4c3a8e6f0b12",
5975+ "created_at": "2026-10-07T14:02:11.000Z",
5976+ "model": "claude-sonnet-5-5",
5977+ "token_id": "tok_01kkr4w7d2c9e5f8h1j3m6n0p2",
5978+ "token_name": "release-notes",
5979+ "input": 1840,
5980+ "output": 512,
5981+ "cache_read": 12000,
5982+ "cache_write": 0,
5983+ "cost_micros": 11200,
5984+ "charged_micros": 11200,
5985+ "status": 200,
5986+ "own_key": false,
5987+ "streamed": true,
5988+ "duration_ms": 4210,
5989+ "error": null
5990+ },
5991+ {
5992+ "id": "gw_1a7e3c5b9d2f4e6a8c0b2d41",
5993+ "created_at": "2026-10-07T13:58:40.000Z",
5994+ "model": "claude-opus-5-5",
5995+ "token_id": "tok_01kkr4w7d2c9e5f8h1j3m6n0p2",
5996+ "token_name": "release-notes",
5997+ "input": 0,
5998+ "output": 0,
5999+ "cache_read": 0,
6000+ "cache_write": 0,
6001+ "cost_micros": 0,
6002+ "charged_micros": 0,
6003+ "status": 402,
6004+ "own_key": false,
6005+ "streamed": false,
6006+ "duration_ms": 38,
6007+ "error": "The flagon-io workspace is out of AI credit and has used this month's included usage, so the AI Gateway refuses requests to g1t's models. An owner can buy AI credit or turn on auto-reload at /flagon-io/-/billing#ai-credit."
6008+ }
6009+ ],
6010+ "next": "gw_1a7e3c5b9d2f4e6a8c0b2d41",
6011+ "retention_days": 30
6012+ },
6013+ "notes": "To send requests, see the AI Gateway guide: POST https://models.g1t.sh/anthropic/v1/messages with a workspace access token that has `models:write`. `charged_micros` is what the request was charged before included usage and AI credit paid for it; the payment itself is on the statement as AI Gateway. Pass `next` as `before` for the next page; it is null on the last."
6014+ },
59646015 "list_invoices": {
59656016 "params": {
59666017 "workspace": "flagon-io"
+3−0
135135 route("POST", "/workspaces/:workspace/ai_credit/checkout", Op::BuyAiCredit, &[]),
136136 route("GET", "/workspaces/:workspace/invoices", Op::ListInvoices, &[]),
137137 route("GET", "/workspaces/:workspace/billing_details", Op::GetBillingDetails, &[]),
138+ // The AI Gateway's log of a workspace's requests.
139+ route("GET", "/workspaces/:workspace/gateway/requests", Op::ListGatewayRequests, &[("limit", "limit"), ("before", "before")]),
138140 // Code owners: the CODEOWNERS file, checked.
139141 route("GET", "/repos/:owner/:name/codeowners/errors", Op::GetCodeownersErrors, &[("ref", "ref")]),
140142 // Security alerts: secrets and vulnerable dependencies.
10571059 assert_eq!(op("POST", "/workspaces/acme/ai_credit/checkout"), Op::BuyAiCredit);
10581060 assert_eq!(op("GET", "/workspaces/acme/invoices"), Op::ListInvoices);
10591061 assert_eq!(op("GET", "/workspaces/acme/billing_details"), Op::GetBillingDetails);
1062+ assert_eq!(op("GET", "/workspaces/acme/gateway/requests"), Op::ListGatewayRequests);
10601063 }
10611064
10621065 #[test]
+3−1
306306 Tool {
307307 name: "billing",
308308 title: "Billing",
309− description: "A workspace's billing: its usage by product, project and day, its budget (the monthly spend limit, alerts and whether usage pauses at it), its AI credit, and its invoices. Amounts are whole millionths of a dollar (`_micros`), or cents (`_cents`) where named. Members read it; changing the budget and buying credit are for owners, as people, and never for g1t's agents.",
309+ description: "A workspace's billing: its usage by product, project and day, its budget (the monthly spend limit, alerts and whether usage pauses at it), its AI credit, its invoices, and its AI Gateway requests. Amounts are whole millionths of a dollar (`_micros`), or cents (`_cents`) where named. Members read it; changing the budget and buying credit are for owners, as people, and never for g1t's agents.",
310310 default_action: Some("usage"),
311311 actions: &[
312312 a("usage", Op::GetUsage, "Usage over a range of days, by product, meter, project and day, and what paid for it"),
316316 a("buy_ai_credit", Op::BuyAiCredit, "A payment page to buy AI credit, for a person to open"),
317317 a("invoices", Op::ListInvoices, "Every invoice, the itemised usage invoices, and the next one so far"),
318318 a("billing_details", Op::GetBillingDetails, "Who invoices are made out to and the payment method on file"),
319+ a("gateway_requests", Op::ListGatewayRequests, "Recent AI Gateway requests: model, tokens, cost, status and token"),
319320 ],
320321 },
321322 Tool {
655656 token_id: "tok_1".to_owned(),
656657 scopes: scopes.map(|scopes| scopes.iter().map(|scope| scope.as_str().to_owned()).collect()),
657658 legacy: false,
659+ name: None,
658660 }
659661 }
660662
+1−0
115115 items: [
116116 { label: 'Integrations', slug: 'guides/integrations' },
117117 { label: 'Model providers', slug: 'guides/models' },
118+ { label: 'AI Gateway', slug: 'guides/ai-gateway' },
118119 { label: 'Webhooks', slug: 'guides/webhooks' },
119120 { label: 'GitHub Actions', slug: 'guides/actions' },
120121 { label: 'Self-hosted runners', slug: 'guides/self-hosted-runners' },
+241−0
1+---
2+title: AI Gateway
3+description: Send your own code's model requests through g1t with a workspace access token, paid from AI credit at the model's price, with a log of every request.
4+---
5+
6+The AI Gateway takes model requests from your own code, in Anthropic's
7+Messages format, and sends them to the model. You point an Anthropic SDK,
8+Claude Code or anything else that speaks that format at one base URL and
9+give it a workspace access token as its API key:
10+
11+| | |
12+| --- | --- |
13+| Base URL | `https://models.g1t.sh/anthropic` |
14+| API key | A workspace access token (`g1t_…`) with the `models:write` scope |
15+
16+Each request is charged to the workspace at the model's price and paid from
17+the plan's included usage and [AI credit](/guides/usage-and-billing/#ai-credit).
18+While the gateway is in beta there is no markup. If the workspace has
19+connected its own Anthropic key, requests go there instead and cost
20+nothing on g1t. Every request is logged with its model, tokens, cost and
21+status. Prompts and answers are never kept.
22+
23+## Before you start
24+
25+You need one of these:
26+
27+- **The workspace on the g1t plan**, with AI credit or this month's
28+ included usage left. See [AI credit](/guides/usage-and-billing/#ai-credit).
29+- **The workspace's own Anthropic key**, connected under
30+ [Integrations](/guides/models/#connect-a-provider). Then the plan is not
31+ needed and nothing is charged.
32+
33+## Make a token
34+
35+The gateway takes a workspace's own token, so its usage is the workspace's
36+and keeps working when the person who set it up leaves. Only owners make
37+them.
38+
39+1. Open the workspace's **Settings → Access tokens**.
40+2. Under **New token**, give it a name, such as `release-notes`. The log
41+ shows each request's token by this name.
42+3. The scopes start on the CI preset. Untick what the code does not need,
43+ and under **AI Gateway** tick `models:write`. A token with only
44+ `models:write` can send model requests and nothing else.
45+4. Choose an expiry and select **Create token**. Copy the token now: it is
46+ not shown again.
47+
48+A personal access token is refused, even with `models:write`: the gateway
49+has to know which workspace to charge. A token with full access has every
50+scope, `models:write` included. See [scopes](/guides/authentication/#scopes).
51+
52+## Send a request
53+
54+The gateway answers the same routes as Anthropic's API, below the base URL:
55+
56+| Route | What it does |
57+| --- | --- |
58+| `POST /anthropic/v1/messages` | A message, streamed (`"stream": true`) or whole. Logged and charged. |
59+| `POST /anthropic/v1/messages/count_tokens` | Counts a request's input tokens. Not logged, and costs nothing. |
60+
61+The token goes in `x-api-key`, or in `Authorization: Bearer`. Request and
62+answer bodies are Anthropic's, unchanged, and so are streamed events.
63+
64+With curl:
65+
66+```sh
67+curl https://models.g1t.sh/anthropic/v1/messages \
68+ -H "x-api-key: $G1T_TOKEN" \
69+ -H "anthropic-version: 2023-06-01" \
70+ -H "content-type: application/json" \
71+ -d '{
72+ "model": "claude-sonnet-5-5",
73+ "max_tokens": 1024,
74+ "messages": [{ "role": "user", "content": "Write a commit message for: fix the login redirect" }]
75+ }'
76+```
77+
78+With Anthropic's TypeScript SDK:
79+
80+```ts
81+import Anthropic from "@anthropic-ai/sdk";
82+
83+const client = new Anthropic({
84+ baseURL: "https://models.g1t.sh/anthropic",
85+ apiKey: process.env.G1T_TOKEN,
86+});
87+
88+const message = await client.messages.create({
89+ model: "claude-sonnet-5-5",
90+ max_tokens: 1024,
91+ messages: [{ role: "user", content: "Write a commit message for: fix the login redirect" }],
92+});
93+```
94+
95+With Anthropic's Python SDK:
96+
97+```python
98+import os
99+
100+import anthropic
101+
102+client = anthropic.Anthropic(
103+ base_url="https://models.g1t.sh/anthropic",
104+ api_key=os.environ["G1T_TOKEN"],
105+)
106+
107+message = client.messages.create(
108+ model="claude-sonnet-5-5",
109+ max_tokens=1024,
110+ messages=[{"role": "user", "content": "Write a commit message for: fix the login redirect"}],
111+)
112+```
113+
114+### Claude Code
115+
116+Set two environment variables before you start it:
117+
118+```sh
119+export ANTHROPIC_BASE_URL=https://models.g1t.sh/anthropic
120+export ANTHROPIC_AUTH_TOKEN=g1t_…
121+claude
122+```
123+
124+Claude Code's own small requests go to Claude Haiku 4.5, which the gateway
125+offers. To choose the main model, also set `ANTHROPIC_MODEL`, such as
126+`claude-opus-5-5`.
127+
128+## Models
129+
130+On g1t's models the gateway offers these. Prices are per million tokens,
131+the provider's list price; cache writes are five-minute ones.
132+
133+| Model | `model` | Input | Output | Cache reads | Cache writes |
134+| --- | --- | --- | --- | --- | --- |
135+| Claude Opus 5.5 | `claude-opus-5-5` | $4.00 | $20.00 | $0.20 | $5.00 |
136+| Claude Sonnet 5.5 | `claude-sonnet-5-5` | $2.00 | $10.00 | $0.20 | $2.50 |
137+| Claude Haiku 4.5 | `claude-haiku-4-5`, `claude-haiku-4-5-20251001` | $1.00 | $5.00 | $0.10 | $1.25 |
138+
139+A request for any other model is refused with `400` before it reaches the
140+provider, and the error names the models offered. On the workspace's own
141+key, a request can name any model that key can use.
142+
143+On g1t's models a request is charged only by its tokens, so what the
144+provider bills some other way is refused with `400` for now:
145+
146+| Not offered on g1t's models yet | In the request |
147+| --- | --- |
148+| Fast mode | `speed` other than `standard` |
149+| Inference in one region | `inference_geo` other than `global` |
150+| Server-side fallbacks | `fallbacks` |
151+| Server tools, such as web search, web fetch and code execution | A tool whose `type` is not your own (`custom` or none) or a client tool (`bash_…`, `text_editor_…`, `computer_…`, `memory_…`) |
152+| Containers and skills | `container` |
153+
154+All of them work on the workspace's own key, which the provider bills. In
155+Claude Code on g1t's models, its web search fails for this reason; the
156+rest of Claude Code works.
157+
158+Anthropic's format is the one served today. OpenAI's format and open
159+models are coming later.
160+
161+## What it costs
162+
163+| Where it goes | You pay |
164+| --- | --- |
165+| g1t's models | Its tokens at the model's price above, with no markup while the gateway is in beta |
166+| The workspace's own Anthropic key | Nothing on g1t. The provider bills you for the model. |
167+
168+On g1t's models:
169+
170+- Each request that used tokens is one line on the statement, under
171+ **AI Gateway**, such as *AI Gateway: Claude Sonnet 5.5, 14,352 tokens,
172+ token release-notes*.
173+- The plan's included usage pays first, then AI credit. Trial credit and
174+ g1t's open-source pool never pay for gateway requests.
175+- It is not an agent run, so the [agent rate](/guides/usage-and-billing/#the-agent-rate)
176+ does not apply.
177+- It counts toward the workspace's [spend limit](/guides/usage-and-billing/#your-spend-limit)
178+ like any other usage, and shows on **Usage** under the AI Gateway product.
179+- A workspace with a 100% discount gets it free through the discount; an
180+ enterprise is invoiced for it after use.
181+
182+### Your own key
183+
184+When the workspace has an Anthropic or Anthropic-compatible model provider
185+under [Integrations](/guides/models/), the gateway sends every request to
186+the first one connected, with its key. Those requests are logged with their
187+tokens and marked **Own key**, and g1t charges nothing for them. Remove the
188+provider and requests go to g1t's models again within a few seconds.
189+
190+## Limits and errors
191+
192+A request on g1t's models is refused before it reaches the model when:
193+
194+- The workspace is over its spend limit.
195+- It is on the plan, and has no AI credit and none of this month's included
196+ usage left. If auto-reload is on, g1t tries it first.
197+- It is not on the g1t plan.
198+
199+Errors are Anthropic's shape, so SDKs raise their usual errors:
200+
201+```json
202+{ "type": "error", "error": { "type": "billing_error", "message": "The acme workspace is out of AI credit …" } }
203+```
204+
205+| Status | `error.type` | Why |
206+| --- | --- | --- |
207+| `400` | `invalid_request_error` | The body is not JSON, the model is not offered, or the request asks for something [not offered on g1t's models yet](#models). |
208+| `401` | `authentication_error` | The token is unknown, expired or deleted. |
209+| `402` | `billing_error` | Out of AI credit, over the spend limit, or not on the plan. The message says what an owner can do. |
210+| `403` | `permission_error` | Not a workspace's token, or it lacks `models:write`. |
211+| `404` | `not_found_error` | A route the gateway does not answer. |
212+
213+An error from the model provider, such as `429` or `529`, comes back as
214+the provider sent it. Refused and failed requests are logged with their
215+status and why, and cost nothing.
216+
217+A deleted token, a provider added under Integrations, or AI credit just
218+bought takes effect within about ten seconds.
219+
220+## See every request
221+
222+The **AI Gateway** page lists the workspace's requests, newest first. Open
223+it from the link under **Usage**, or at `g1t.sh/<workspace>/-/gateway`.
224+Every member can see it.
225+
226+| Column | |
227+| --- | --- |
228+| Time | When it was sent. Hover for the exact time, how long it took and whether it streamed. |
229+| Model | The model it named. On the workspace's own key, the one that answered. |
230+| Input, Output, Cache read, Cache write | Its tokens by kind. |
231+| Cost | What it was charged, before included usage and AI credit paid for it, or **Own key**. |
232+| Status | The status it was answered with. Hover a refusal or failure for why. |
233+| Token | The name of the token that sent it. |
234+
235+Requests are kept 30 days.
236+
237+From code, list them with
238+[`GET /workspaces/{workspace}/gateway/requests`](/reference/api/billing/list-gateway-requests/),
239+or the `billing` MCP tool's
240+[`gateway_requests`](/reference/mcp/#billing) action. Both need
241+`models:read`, which the Read only and Agent presets include.
+3−0
328328 | Workspace | `workspace:read`, `access:read`, `webhooks:read`, `secrets:read` |
329329 | Billing | `billing:read`, `billing:write` |
330330 | Runners | `runners:read` |
331+| AI Gateway | `models:read`, `models:write` |
331332 | Dangerous | `repo:admin`, `packages:delete`, `workspace:admin`, `access:admin`, `webhooks:admin`, `secrets:admin`, `runners:admin` |
332333
333334 Ticking a higher level ticks the lower ones of its resource and greys
371372 | `secrets:admin` | Set and delete secrets and variables |
372373 | `runners:read` | See [self-hosted runners](/guides/self-hosted-runners/), their groups and where agents run. Not in the Agent preset. |
373374 | `runners:admin` | Register and remove self-hosted runners, change their groups and settings |
375+| `models:read` | See the workspace's [AI Gateway](/guides/ai-gateway/) requests: their models, tokens, cost and status |
376+| `models:write` | Send model requests through the [AI Gateway](/guides/ai-gateway/), which uses the workspace's AI credit. Only a workspace's own token can send them. Not in any preset but full access. |
374377
375378 Every operation of the API and the MCP server needs exactly one of these,
376379 except `whoami` (`GET /user`), which any token may use. Each endpoint's page
+3−0
1818 kind of work, which provider and model it runs on. Each provider bills
1919 you for the model directly. Open to every workspace now.
2020
21+To call models from your own code with a workspace token, paid from the
22+same AI credit, use the [AI Gateway](/guides/ai-gateway/).
23+
2124 ## Auto
2225
2326 On g1t's models you do not have to pick a model. **Auto**, the default,
+1−1
123123 | Agent models | A run | What the provider charged | The provider's price, from [AI credit](#ai-credit) |
124124 | g1t agent rate | Million tokens a run uses (input, output and cached), [weighted by kind](#the-agent-rate) | — | $0.25, from Oct 22, 2026 |
125125 | g1t agent rate, your own model key | The same, on runs that use [your own provider](/guides/models/) | — | $0.25, from Oct 22, 2026 |
126−| AI Gateway | A request | What the provider charged | The provider's price: free of markup during beta |
126+| [AI Gateway](/guides/ai-gateway/) | A request | What the provider charged | The model's list price per token: free of markup during beta |
127127 | Sandbox time (agents, workflows, the merge queue) | Second | About $0.001 a minute | About $0.0012 a minute |
128128 | [Larger machines](#workflow-jobs-on-larger-machines) for workflow jobs (`g1t-2core`, `g1t-4core`) | Second | About 2.8 and 5.1 times a sandbox second | Cost + 20% |
129129 | Deploy builds | Second | About $0.001 a minute | About $0.0012 a minute |
+2−1
6363 gets a [pull request that upgrades it](/guides/security/).
6464 </Card>
6565 <Card title="Your models, your tools" icon="plug">
66− Use g1t's models or [your own providers](/guides/models/), and pull context
66+ Use g1t's models or [your own providers](/guides/models/), call the same
67+ models from your own code through the [AI Gateway](/guides/ai-gateway/), and pull context
6768 from [Sentry, Jira and Linear](/guides/integrations/).
6869 </Card>
6970 <Card title="Everything has an API" icon="book-open">
+1−1
197197 | [Accounts](/reference/api/accounts/whoami/) | Signing in from a tool, and who a token acts as. |
198198 | [Workspaces](/reference/api/workspaces/create-workspace/) | Creating a workspace. |
199199 | [Notifications](/reference/api/notifications/list-notifications/) | Your inbox: its threads, why you were told of each, marking them read, done, saved or snoozed, and what you subscribe to and watch. See [your inbox](/guides/inbox/). |
200−| [Billing](/reference/api/billing/get-usage/) | A workspace's usage by product, project and day, its budget, its AI credit and its invoices. See [usage and billing](/guides/usage-and-billing/). |
200+| [Billing](/reference/api/billing/get-usage/) | A workspace's usage by product, project and day, its budget, its AI credit, its invoices and its [AI Gateway](/guides/ai-gateway/) requests. See [usage and billing](/guides/usage-and-billing/). |
201201 | [Invites](/reference/api/invites/list-invites/) | Your invites while g1t is invite-only, and inviting people into a workspace by email. |
202202 | [Repositories](/reference/api/repositories/list-repos/) | A repository, how it handles pull requests, and its timeline. |
203203 | [Access](/reference/api/access/list-collaborators/) | Who has which role on a repository, invitations, outside collaborators, and a workspace's base permission. |
+3−2
565565
566566 ## `billing`
567567
568−A workspace's billing: its usage, its budget, its AI credit and its
569−invoices. `usage` is the default action. Amounts are whole millionths of a
568+A workspace's billing: its usage, its budget, its AI credit, its
569+invoices and its [AI Gateway](/guides/ai-gateway/) requests. `usage` is the default action. Amounts are whole millionths of a
570570 dollar (`_micros`), or cents where a field says `_cents`. Members of the
571571 workspace read it, a workspace's own token included. Changing the budget
572572 and buying AI credit are for its owners, as people: signed in or with a
583583 | [`buy_ai_credit`](/reference/api/billing/buy-ai-credit/) | A payment page (`url`) to buy `amount_cents` of credit, in whole dollars from $10 to $1,000, for a person to open and pay; it returns to the workspace's billing page. Owners, as people. | `workspace`, `amount_cents` | `billing:write` |
584584 | [`invoices`](/reference/api/billing/list-invoices/) | Every invoice (`invoices`, in cents), g1t's itemised usage invoices (`usage_invoices`), and what the next one comes to so far (`upcoming`). | `workspace` | `billing:read` |
585585 | [`billing_details`](/reference/api/billing/get-billing-details/) | Who invoices are made out to, and the payment method on file as far as it is safe to show. | `workspace` | `billing:read` |
586+| [`gateway_requests`](/reference/api/billing/list-gateway-requests/) | The workspace's recent [AI Gateway](/guides/ai-gateway/) requests, newest first: model, tokens by kind, `cost_micros`, `charged_micros`, `status`, `own_key` and the token that sent each. `limit` (50, at most 200) and `before` (the last page's `next`) page through them. Kept 30 days. | `workspace` | `models:read` |
586587
587588 ## `notifications`
588589
+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

+0−0

Binary or large file; its contents are not shown.

This change is too large to show in full.