Admin
Package: agentrouter.admin.v1 Service: AdminService
Endpoints
Ping
What it does: Endpoint for health checks and authentication testing
Request body: None.
Response fields:
| Field | Required | Description |
|---|---|---|
message | no | Human-readable status message (e.g. "pong"). |
timestamp | no | Server time when the ping was handled. |
{"signatures":{"go":"func (x *AdminClient) Ping(ctx context.Context, req *adminv1.PingRequest) (*adminv1.PingResponse, error)","python":"ping(req: admin_pb2.PingRequest) -\u003e PingResponse","typescript":"ping(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.PingRequestSchema\u003e): Promise\u003cPingResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/ping\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.PingRequest{}\n\n\tresp, err := client.Admin().Ping(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/ping\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.PingRequest()\ntry:\n result = client.admin.ping(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.ping(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/ping\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/ping","slug":"ping"}
Create workspace
Changed in v0.9.0 (bug fixes): These changes are now audited: data plane changes made through the workspace API, guardrail pattern and fallback-policy changes, refused gateway attaches, data plane upgrade outcomes, and the data plane URL, token revocations and MCP catalog entries a data plane writes.
What it does: Create workspace
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Customer (tenant) slug that will own the workspace. |
workspace_id | no | Caller-chosen workspace slug, unique within the customer. |
name | no | Optional human-readable display name. |
description | no | Optional free-text description. |
labels | no | Optional user-defined key/value labels for organization/filtering. |
project_id | no | Optional project this workspace belongs to. Empty = default project. |
Response fields:
| Field | Required | Description |
|---|---|---|
workspace | no | The newly created workspace. |
{"signatures":{"go":"func (x *AdminClient) CreateWorkspace(ctx context.Context, req *adminv1.CreateWorkspaceRequest) (*adminv1.CreateWorkspaceResponse, error)","python":"create_workspace(req: admin_pb2.CreateWorkspaceRequest) -\u003e CreateWorkspaceResponse","typescript":"createWorkspace(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.CreateWorkspaceRequestSchema\u003e): Promise\u003cCreateWorkspaceResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"workspace_id\": \"...\",\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {},\n \"project_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.CreateWorkspaceRequest{}\n\n\tresp, err := client.Admin().CreateWorkspace(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/createworkspace\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.CreateWorkspaceRequest()\ntry:\n result = client.admin.create_workspace(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.createWorkspace(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"workspace_id\": \"...\",\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {},\n \"project_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/workspaces","slug":"create-workspace"}
List workspaces
Changed in v0.11.0 (bug fixes): Listing data planes now returns next_page_token when more remain, and passing it as page_token returns the next page. A token that is malformed or from a listing for another customer is refused with INVALID_ARGUMENT. Configuration changes now reach every data plane of a customer with more than 1,000 of them.
What it does: List workspaces
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Optional filter: only return workspaces owned by this customer slug. |
page_size | no | Max workspaces to return per page (0 = server default). |
page_token | no | Opaque cursor from a previous response's next_page_token. |
Response fields:
| Field | Required | Description |
|---|---|---|
workspaces | no | Page of matching workspaces. |
next_page_token | no | Cursor for the next page; empty when there are no more results. |
{"signatures":{"go":"func (x *AdminClient) ListWorkspaces(ctx context.Context, req *adminv1.ListWorkspacesRequest) (*adminv1.ListWorkspacesResponse, error)","python":"list_workspaces(req: admin_pb2.ListWorkspacesRequest) -\u003e ListWorkspacesResponse","typescript":"listWorkspaces(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListWorkspacesRequestSchema\u003e): Promise\u003cListWorkspacesResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListWorkspacesRequest{}\n\n\tresp, err := client.Admin().ListWorkspaces(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listworkspaces\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListWorkspacesRequest()\ntry:\n result = client.admin.list_workspaces(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listWorkspaces(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/workspaces","slug":"list-workspaces"}
Get workspace
What it does: Get workspace
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Workspace UUID (the internal id, not the customer-chosen workspace_id). |
Response fields:
| Field | Required | Description |
|---|---|---|
workspace | no | The requested workspace. |
{"signatures":{"go":"func (x *AdminClient) GetWorkspace(ctx context.Context, req *adminv1.GetWorkspaceRequest) (*adminv1.GetWorkspaceResponse, error)","python":"get_workspace(req: admin_pb2.GetWorkspaceRequest) -\u003e GetWorkspaceResponse","typescript":"getWorkspace(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetWorkspaceRequestSchema\u003e): Promise\u003cGetWorkspaceResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetWorkspaceRequest{}\n\n\tresp, err := client.Admin().GetWorkspace(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getworkspace\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetWorkspaceRequest()\ntry:\n result = client.admin.get_workspace(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getWorkspace(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/workspaces/{id}","slug":"get-workspace"}
Update workspace
Changed in v0.9.0 (bug fixes): These changes are now audited: data plane changes made through the workspace API, guardrail pattern and fallback-policy changes, refused gateway attaches, data plane upgrade outcomes, and the data plane URL, token revocations and MCP catalog entries a data plane writes.
Changed in v0.7.0 (new features): A data plane can now repair itself when its doctor reports RBAC objects or CRDs its chart declares as missing or changed, writing back what the chart says. Turn it on per data plane with auto_repair. A run makes at most two attempts, and the data plane's health then shows a SelfRepairHealthy issue carrying the error. A run that escalates also keeps a doctor bundle, which happens when both attempts fail on the same step or the data plane reports on neither.
What it does: Update workspace
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Workspace UUID to update. |
name | no | New display name; unset leaves the existing value. |
description | no | New description; unset leaves the existing value. |
labels | no | Replacement set of labels. |
auto_upgrade | no | Flip unattended upgrades on or off; unset leaves the existing value. |
auto_repair | no | Flip unattended self-repair on or off; unset leaves the existing value. |
Response fields:
| Field | Required | Description |
|---|---|---|
workspace | no | The updated workspace. |
{"signatures":{"go":"func (x *AdminClient) UpdateWorkspace(ctx context.Context, req *adminv1.UpdateWorkspaceRequest) (*adminv1.UpdateWorkspaceResponse, error)","python":"update_workspace(req: admin_pb2.UpdateWorkspaceRequest) -\u003e UpdateWorkspaceResponse","typescript":"updateWorkspace(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpdateWorkspaceRequestSchema\u003e): Promise\u003cUpdateWorkspaceResponse\u003e","curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {},\n \"auto_upgrade\": false,\n \"auto_repair\": false\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpdateWorkspaceRequest{}\n\n\tresp, err := client.Admin().UpdateWorkspace(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/updateworkspace\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpdateWorkspaceRequest()\ntry:\n result = client.admin.update_workspace(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.updateWorkspace(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {},\n \"auto_upgrade\": false,\n \"auto_repair\": false\n }'"},"persona":"Admin","httpVerb":"PATCH","httpPath":"/admin/v1/workspaces/{id}","slug":"update-workspace"}
Set workspace URL
Changed in v0.9.0 (bug fixes): These changes are now audited: data plane changes made through the workspace API, guardrail pattern and fallback-policy changes, refused gateway attaches, data plane upgrade outcomes, and the data plane URL, token revocations and MCP catalog entries a data plane writes.
Changed in v0.8.0 (security updates): SetWorkspaceURL and SetDataplaneURL refuse to set or clear a data plane URL with FailedPrecondition when another organization uses the same data plane ID. The URL was stored under the ID alone, so the write also changed the other organization's data plane. CreateServiceAccount with a serve URL for such an ID is refused too when no URL is stored for that ID yet. The Admin Console's System Settings save does not check this yet; it moves onto SetDataplaneURL in a later release.
Changed in v0.7.0 (deprecations): Setting a data plane's or a project gateway's address through the admin API is deprecated. A 0.7 data plane reports its own address from global.gateway.hostnames in its serve-helm values. SetDataplaneURL, its SetWorkspaceURL alias, SetProjectGatewayURL and the url field of CreateProjectGateway and UpdateProjectGateway keep working. A data plane before 0.7 cannot declare hostnames, so these calls stay until no supported data plane predates 0.7.
Changed in v0.4.0 (security updates): Claiming a hostname that is already in use no longer exposes details about the existing configuration. The conflict message now says only that the hostname is in use, preventing a rejected claim from revealing information about another organization's resources.
What it does: Set the customer-facing gateway URL for a workspace data plane. Writes system_settings.dataplane-url:<workspace_id> and optionally fires a PROXY_URL config event. Deprecated (fraser#8586): SetDataplaneURL, which superseded this call, is deprecated too. A data plane reports its own address from global.gateway.hostnames in its serve-helm values, and the management plane mirrors it read-only. This stays working in 0.6; removal is proposed for 0.8.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Workspace UUID whose data-plane URL is being set. |
url | no | url is the full https:// URL of the data plane's customer-facing gateway endpoint. |
trigger_update | no | trigger_update fires a PROXY_URL config event to the data plane after persisting the URL. |
Response fields:
| Field | Required | Description |
|---|---|---|
workspace | no | The workspace reflecting the new data-plane URL. |
{"signatures":{"go":"func (x *AdminClient) SetWorkspaceURL(ctx context.Context, req *adminv1.SetWorkspaceURLRequest) (*adminv1.SetWorkspaceURLResponse, error)","python":"set_workspace_url(req: admin_pb2.SetWorkspaceURLRequest) -\u003e SetWorkspaceURLResponse","typescript":"setWorkspaceURL(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.SetWorkspaceURLRequestSchema\u003e): Promise\u003cSetWorkspaceURLResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces/01H.../url\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"url\": \"...\",\n \"trigger_update\": false\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.SetWorkspaceURLRequest{}\n\n\tresp, err := client.Admin().SetWorkspaceURL(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/setworkspaceurl\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.SetWorkspaceURLRequest()\ntry:\n result = client.admin.set_workspace_url(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.setWorkspaceURL(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces/01H.../url\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"url\": \"...\",\n \"trigger_update\": false\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/workspaces/{id}/url","slug":"set-workspace-url"}
Set workspace project
Changed in v0.9.0 (bug fixes): These changes are now audited: data plane changes made through the workspace API, guardrail pattern and fallback-policy changes, refused gateway attaches, data plane upgrade outcomes, and the data plane URL, token revocations and MCP catalog entries a data plane writes.
What it does: Assign workspace to a project (or clear back to default project by omitting project_id)
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Workspace UUID to reassign. |
project_id | no | project_id to assign. Omit or set to empty string to clear back to the default project (NULL). |
Response fields:
| Field | Required | Description |
|---|---|---|
workspace | no | The workspace with its updated project assignment. |
{"signatures":{"go":"func (x *AdminClient) SetWorkspaceProject(ctx context.Context, req *adminv1.SetWorkspaceProjectRequest) (*adminv1.SetWorkspaceProjectResponse, error)","python":"set_workspace_project(req: admin_pb2.SetWorkspaceProjectRequest) -\u003e SetWorkspaceProjectResponse","typescript":"setWorkspaceProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.SetWorkspaceProjectRequestSchema\u003e): Promise\u003cSetWorkspaceProjectResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces/01H.../project\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.SetWorkspaceProjectRequest{}\n\n\tresp, err := client.Admin().SetWorkspaceProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/setworkspaceproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.SetWorkspaceProjectRequest()\ntry:\n result = client.admin.set_workspace_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.setWorkspaceProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces/01H.../project\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/workspaces/{id}/project","slug":"set-workspace-project"}
Delete workspace
Changed in v0.9.0 (bug fixes): These changes are now audited: data plane changes made through the workspace API, guardrail pattern and fallback-policy changes, refused gateway attaches, data plane upgrade outcomes, and the data plane URL, token revocations and MCP catalog entries a data plane writes.
Changed in v0.7.0 (behaviour changes): Deleting a data plane now refuses while it is the only one serving a project, and the refusal names up to ten of those projects and reports how many there are in all. A data plane whose projects are all served by another one is deleted as before. Detaching a project from its last data plane is still allowed and now writes a PROJECT_SERVED_NOWHERE audit entry naming the project and that data plane, so the audit log carries a new action type from this release on.
What it does: Delete workspace (soft delete)
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Workspace UUID to soft-delete. |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the workspace was deleted. |
deleted_at | no | When the soft delete took effect. |
{"signatures":{"go":"func (x *AdminClient) DeleteWorkspace(ctx context.Context, req *adminv1.DeleteWorkspaceRequest) (*adminv1.DeleteWorkspaceResponse, error)","python":"delete_workspace(req: admin_pb2.DeleteWorkspaceRequest) -\u003e DeleteWorkspaceResponse","typescript":"deleteWorkspace(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.DeleteWorkspaceRequestSchema\u003e): Promise\u003cDeleteWorkspaceResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.DeleteWorkspaceRequest{}\n\n\tresp, err := client.Admin().DeleteWorkspace(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/deleteworkspace\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.DeleteWorkspaceRequest()\ntry:\n result = client.admin.delete_workspace(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.deleteWorkspace(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/workspaces/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/admin/v1/workspaces/{id}","slug":"delete-workspace"}
Create dataplane
What it does: Register a data plane.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Customer (tenant) slug that will own the data plane. |
dataplane_id | no | Caller-chosen data plane slug, unique within the customer. |
name | no | Optional human-readable display name. |
description | no | Optional free-text description. |
labels | no | Optional user-defined key/value labels. |
project_id | no | Optional project this data plane belongs to. Empty = default project. |
Response fields:
| Field | Required | Description |
|---|---|---|
dataplane | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) CreateDataplane(ctx context.Context, req *adminv1.CreateDataplaneRequest) (*adminv1.CreateDataplaneResponse, error)","python":"create_dataplane(req: admin_pb2.CreateDataplaneRequest) -\u003e CreateDataplaneResponse","typescript":"createDataplane(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.CreateDataplaneRequestSchema\u003e): Promise\u003cCreateDataplaneResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"dataplane_id\": \"...\",\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {},\n \"project_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.CreateDataplaneRequest{}\n\n\tresp, err := client.Admin().CreateDataplane(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/createdataplane\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.CreateDataplaneRequest()\ntry:\n result = client.admin.create_dataplane(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.createDataplane(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"dataplane_id\": \"...\",\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {},\n \"project_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/dataplanes","slug":"create-dataplane"}
List dataplanes
Changed in v0.11.0 (bug fixes): Listing data planes now returns next_page_token when more remain, and passing it as page_token returns the next page. A token that is malformed or from a listing for another customer is refused with INVALID_ARGUMENT. Configuration changes now reach every data plane of a customer with more than 1,000 of them.
Changed in v0.9.0 (new features): Data planes now carry stored_url, the URL stored for the data plane. When another organization uses the same data plane ID, stored_url is the first hostname your data plane declares, or empty. The new ClearSystemSetting unsets the proxy URL setting or the stored URL of one data plane.
Changed in v0.9.0 (deprecations): stored_url on data planes and ClearSystemSetting are deprecated. They go with the stored data plane URL in a later release.
Changed in v0.7.0 (new features): A data plane now reports each whitelisted field on which it serves something other than the bundle the management plane sent, with both values, and a project reports the fields its data planes disagree on. The management plane labels each difference as an intended override, as a data plane that has not pulled yet, or as one nothing explains. An administrator or the project's owner acknowledges a difference, and one that clears stays on record until then.
What it does: List data planes.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | undocumented |
page_size | no | undocumented |
page_token | no | undocumented |
Response fields:
| Field | Required | Description |
|---|---|---|
dataplanes | no | undocumented |
next_page_token | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) ListDataplanes(ctx context.Context, req *adminv1.ListDataplanesRequest) (*adminv1.ListDataplanesResponse, error)","python":"list_dataplanes(req: admin_pb2.ListDataplanesRequest) -\u003e ListDataplanesResponse","typescript":"listDataplanes(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListDataplanesRequestSchema\u003e): Promise\u003cListDataplanesResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListDataplanesRequest{}\n\n\tresp, err := client.Admin().ListDataplanes(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listdataplanes\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListDataplanesRequest()\ntry:\n result = client.admin.list_dataplanes(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listDataplanes(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/dataplanes","slug":"list-dataplanes"}
Get dataplane
Changed in v0.9.0 (new features): Data planes now carry stored_url, the URL stored for the data plane. When another organization uses the same data plane ID, stored_url is the first hostname your data plane declares, or empty. The new ClearSystemSetting unsets the proxy URL setting or the stored URL of one data plane.
Changed in v0.9.0 (deprecations): stored_url on data planes and ClearSystemSetting are deprecated. They go with the stored data plane URL in a later release.
Changed in v0.7.0 (new features): A data plane now reports each whitelisted field on which it serves something other than the bundle the management plane sent, with both values, and a project reports the fields its data planes disagree on. The management plane labels each difference as an intended override, as a data plane that has not pulled yet, or as one nothing explains. An administrator or the project's owner acknowledges a difference, and one that clears stays on record until then.
What it does: Get a data plane.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | undocumented |
Response fields:
| Field | Required | Description |
|---|---|---|
dataplane | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) GetDataplane(ctx context.Context, req *adminv1.GetDataplaneRequest) (*adminv1.GetDataplaneResponse, error)","python":"get_dataplane(req: admin_pb2.GetDataplaneRequest) -\u003e GetDataplaneResponse","typescript":"getDataplane(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetDataplaneRequestSchema\u003e): Promise\u003cGetDataplaneResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetDataplaneRequest{}\n\n\tresp, err := client.Admin().GetDataplane(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getdataplane\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetDataplaneRequest()\ntry:\n result = client.admin.get_dataplane(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getDataplane(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/dataplanes/{id}","slug":"get-dataplane"}
Update dataplane
Changed in v0.7.0 (new features): A data plane can now repair itself when its doctor reports RBAC objects or CRDs its chart declares as missing or changed, writing back what the chart says. Turn it on per data plane with auto_repair. A run makes at most two attempts, and the data plane's health then shows a SelfRepairHealthy issue carrying the error. A run that escalates also keeps a doctor bundle, which happens when both attempts fail on the same step or the data plane reports on neither.
What it does: Update a data plane.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | undocumented |
name | no | undocumented |
description | no | undocumented |
labels | no | undocumented |
auto_upgrade | no | Mirrors UpdateWorkspaceRequest.auto_upgrade. |
auto_repair | no | Mirrors UpdateWorkspaceRequest.auto_repair. |
Response fields:
| Field | Required | Description |
|---|---|---|
dataplane | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) UpdateDataplane(ctx context.Context, req *adminv1.UpdateDataplaneRequest) (*adminv1.UpdateDataplaneResponse, error)","python":"update_dataplane(req: admin_pb2.UpdateDataplaneRequest) -\u003e UpdateDataplaneResponse","typescript":"updateDataplane(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpdateDataplaneRequestSchema\u003e): Promise\u003cUpdateDataplaneResponse\u003e","curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {},\n \"auto_upgrade\": false,\n \"auto_repair\": false\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpdateDataplaneRequest{}\n\n\tresp, err := client.Admin().UpdateDataplane(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/updatedataplane\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpdateDataplaneRequest()\ntry:\n result = client.admin.update_dataplane(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.updateDataplane(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {},\n \"auto_upgrade\": false,\n \"auto_repair\": false\n }'"},"persona":"Admin","httpVerb":"PATCH","httpPath":"/admin/v1/dataplanes/{id}","slug":"update-dataplane"}
Set dataplane URL
Changed in v0.8.0 (security updates): SetWorkspaceURL and SetDataplaneURL refuse to set or clear a data plane URL with FailedPrecondition when another organization uses the same data plane ID. The URL was stored under the ID alone, so the write also changed the other organization's data plane. CreateServiceAccount with a serve URL for such an ID is refused too when no URL is stored for that ID yet. The Admin Console's System Settings save does not check this yet; it moves onto SetDataplaneURL in a later release.
Changed in v0.7.0 (deprecations): Setting a data plane's or a project gateway's address through the admin API is deprecated. A 0.7 data plane reports its own address from global.gateway.hostnames in its serve-helm values. SetDataplaneURL, its SetWorkspaceURL alias, SetProjectGatewayURL and the url field of CreateProjectGateway and UpdateProjectGateway keep working. A data plane before 0.7 cannot declare hostnames, so these calls stay until no supported data plane predates 0.7.
Changed in v0.4.0 (security updates): Claiming a hostname that is already in use no longer exposes details about the existing configuration. The conflict message now says only that the hostname is in use, preventing a rejected claim from revealing information about another organization's resources.
Deprecated
What it does: Set the customer-facing advertised URL for a data plane. Deprecated (fraser#8586): a data plane reports its own address from global.gateway.hostnames in its serve-helm values, and the management plane mirrors it read-only. This stays working in 0.6; removal is proposed for 0.8.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | undocumented |
url | no | undocumented |
trigger_update | no | undocumented |
Response fields:
| Field | Required | Description |
|---|---|---|
dataplane | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) SetDataplaneURL(ctx context.Context, req *adminv1.SetDataplaneURLRequest) (*adminv1.SetDataplaneURLResponse, error)","python":"set_dataplane_url(req: admin_pb2.SetDataplaneURLRequest) -\u003e SetDataplaneURLResponse","typescript":"setDataplaneURL(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.SetDataplaneURLRequestSchema\u003e): Promise\u003cSetDataplaneURLResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../url\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"url\": \"...\",\n \"trigger_update\": false\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.SetDataplaneURLRequest{}\n\n\tresp, err := client.Admin().SetDataplaneURL(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/setdataplaneurl\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.SetDataplaneURLRequest()\ntry:\n result = client.admin.set_dataplane_url(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.setDataplaneURL(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../url\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"url\": \"...\",\n \"trigger_update\": false\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/dataplanes/{id}/url","slug":"set-dataplane-url"}
Set dataplane project
What it does: Assign a data plane to a project (omit project_id to clear to default).
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | undocumented |
project_id | no | undocumented |
Response fields:
| Field | Required | Description |
|---|---|---|
dataplane | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) SetDataplaneProject(ctx context.Context, req *adminv1.SetDataplaneProjectRequest) (*adminv1.SetDataplaneProjectResponse, error)","python":"set_dataplane_project(req: admin_pb2.SetDataplaneProjectRequest) -\u003e SetDataplaneProjectResponse","typescript":"setDataplaneProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.SetDataplaneProjectRequestSchema\u003e): Promise\u003cSetDataplaneProjectResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../project\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.SetDataplaneProjectRequest{}\n\n\tresp, err := client.Admin().SetDataplaneProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/setdataplaneproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.SetDataplaneProjectRequest()\ntry:\n result = client.admin.set_dataplane_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.setDataplaneProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../project\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/dataplanes/{id}/project","slug":"set-dataplane-project"}
List dataplane projects
Changed in v0.7.0 (new features): A data plane can now be labelled with the projects it serves, naming a data plane and a project rather than a gateway. The data plane picks that project's configuration up on its next config update, and drops it on the next one after the label is removed. Removing the last label serving a project is refused, because its keys would then admit nowhere, unless the call sets acknowledge_last_endpoint to remove it anyway; the response then reports served_nowhere so the caller can tell its owners.
Changed in v0.7.0 (new features): Each project label now says when that data plane first answered a request for the project successfully, in a new verified_at field. It is per project and data plane, so another project's traffic on the same data plane never sets it, and applying a label again clears it until the next success. Each label also reports the config pull before it, as target_revision, held_revision and config_current.
What it does: List the labels a customer holds, which are the (data plane, project) pairs recording which projects each data plane serves (fraser#8587). A label is the project itself selected on a data plane, so it has no lifecycle of its own and there is nothing here to create or name. Filter by dataplane_id for one data plane's own record, by project_id for the data planes serving one project, or by neither for the whole customer, which answers both directions in one request. The answer comes from dataplane_projects rather than from the project gateway join, so a data plane that has never converged still reads as serving what it is labelled with: the question is which projects the management plane distributes to it, not which ones it has already pulled.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
dataplane_id | no | Optional filter: only the labels this data plane carries. |
project_id | no | Optional filter: only the data planes serving this project. |
Response fields:
| Field | Required | Description |
|---|---|---|
labels | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) ListDataplaneProjects(ctx context.Context, req *adminv1.ListDataplaneProjectsRequest) (*adminv1.ListDataplaneProjectsResponse, error)","python":"list_dataplane_projects(req: admin_pb2.ListDataplaneProjectsRequest) -\u003e ListDataplaneProjectsResponse","typescript":"listDataplaneProjects(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListDataplaneProjectsRequestSchema\u003e): Promise\u003cListDataplaneProjectsResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../dataplane-projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListDataplaneProjectsRequest{}\n\n\tresp, err := client.Admin().ListDataplaneProjects(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listdataplaneprojects\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListDataplaneProjectsRequest()\ntry:\n result = client.admin.list_dataplane_projects(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listDataplaneProjects(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../dataplane-projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/dataplane-projects","slug":"list-dataplane-projects"}
Add dataplane project
Changed in v0.11.0 (bug fixes): Changes that check a data plane's version, such as provider overrides, shared and catch-all hostnames, OIDC contracts and the newer rate-limit dimensions, no longer refuse a data plane on 0.11.0 or newer that was just upgraded or has had no configuration change for a day, because it now reports its version on every poll. A data plane silent for 24 hours is refused as down, disconnected or older than 0.11.0, with a prompt to check its connection and build.
Changed in v0.10.0 (behaviour changes): Writing a project's OIDC contract is refused on Agent Router Service (SaaS). Enabling a contract is refused while a data plane serving the project runs a build older than 0.10.0 or has not reported its build, and so is attaching a project whose contract is enabled to such a data plane. Each refusal names the data plane.
Changed in v0.7.0 (new features): A data plane can now be labelled with the projects it serves, naming a data plane and a project rather than a gateway. The data plane picks that project's configuration up on its next config update, and drops it on the next one after the label is removed. Removing the last label serving a project is refused, because its keys would then admit nowhere, unless the call sets acknowledge_last_endpoint to remove it anyway; the response then reports served_nowhere so the caller can tell its owners.
What it does: Label a data plane with a project, so it serves that project's configuration from its next config update (fraser#8591). Idempotent: labelling a data plane that already serves the project leaves the label alone and reports the same success. The project's keys admit on this data plane once its pull lands, not when this call returns, and neither the project nor any other data plane serving it is modified. No hostname, DNS record or certificate takes part. Labelling a data plane with a SECOND project needs that data plane to host more than one project gateway, and this refuses with FAILED_PRECONDITION naming the reason while it hosts a single one.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
dataplane_id | no | Data plane to label. |
project_id | no | Project the data plane is to serve. It must already exist: a label is the project itself, so nothing here creates one. |
Response fields:
| Field | Required | Description |
|---|---|---|
labels | no | The data plane's labels after the call, so a caller renders the new set without a second read. |
warnings | no | Conditions that leave the label true but unserved, such as a project with no models enabled. Carried from the underlying attach. |
{"signatures":{"go":"func (x *AdminClient) AddDataplaneProject(ctx context.Context, req *adminv1.AddDataplaneProjectRequest) (*adminv1.AddDataplaneProjectResponse, error)","python":"add_dataplane_project(req: admin_pb2.AddDataplaneProjectRequest) -\u003e AddDataplaneProjectResponse","typescript":"addDataplaneProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.AddDataplaneProjectRequestSchema\u003e): Promise\u003cAddDataplaneProjectResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../dataplanes/01H.../projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.AddDataplaneProjectRequest{}\n\n\tresp, err := client.Admin().AddDataplaneProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/adddataplaneproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.AddDataplaneProjectRequest()\ntry:\n result = client.admin.add_dataplane_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.addDataplaneProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../dataplanes/01H.../projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/dataplanes/{dataplane_id}/projects","slug":"add-dataplane-project"}
Remove dataplane project
Changed in v0.7.0 (new features): A data plane can now be labelled with the projects it serves, naming a data plane and a project rather than a gateway. The data plane picks that project's configuration up on its next config update, and drops it on the next one after the label is removed. Removing the last label serving a project is refused, because its keys would then admit nowhere, unless the call sets acknowledge_last_endpoint to remove it anyway; the response then reports served_nowhere so the caller can tell its owners.
Changed in v0.7.0 (bug fixes): Removing the last project from a data plane that has a single gateway now takes the project's label off, reports served_nowhere and records PROJECT_SERVED_NOWHERE in the audit log. Before, the call answered removed=true while the label stayed on the data plane, and neither was recorded.
Changed in v0.7.0 (bug fixes): Removing a project from a data plane now takes the label off even when the data plane's configuration update fails, so a response with removed=true no longer lists the label it removed. Removing a label left behind by an earlier removal records PROJECT_SERVED_NOWHERE when it was the project's last one.
What it does: Remove a project's label from a data plane, which clears that project's configuration there on its next update (fraser#8591). Removing a label another data plane also carries costs the project nothing. Removing the last one takes the project's last endpoint away, so this RPC refuses that case with FAILED_PRECONDITION naming the project (fraser#9425): label another data plane with it first, or remove the label deliberately through the path that tells its owners. Removing a label the data plane does not carry is an idempotent no-op reporting removed=false. Until the data plane's next pull lands it still holds the old configuration and the project's keys still admit there.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
dataplane_id | no | Data plane to take the label off. |
project_id | no | Project to stop serving here. |
acknowledge_last_endpoint | no | The caller has been told this data plane is the last one serving the project and chose to leave it served by nothing. Without this, a removal that would strand the project is refused (fraser#9425); with it, the removal proceeds and the outcome is recorded (see RemoveDataplaneProjectResponse.served_nowhere and the PROJECT_SERVED_NOWHERE audit action) so the project's owners are told rather than finding out when their keys stop working. |
Response fields:
| Field | Required | Description |
|---|---|---|
removed | no | False when the data plane carried no such label, which is a no-op rather than an error. |
labels | no | The data plane's labels after the call. |
served_nowhere | no | True when this removal left the project served by no data plane at all. Set only when removed is also true; the console reads this instead of inferring it, so it can say so directly rather than the operator discovering it when the project's keys stop working. |
{"signatures":{"go":"func (x *AdminClient) RemoveDataplaneProject(ctx context.Context, req *adminv1.RemoveDataplaneProjectRequest) (*adminv1.RemoveDataplaneProjectResponse, error)","python":"remove_dataplane_project(req: admin_pb2.RemoveDataplaneProjectRequest) -\u003e RemoveDataplaneProjectResponse","typescript":"removeDataplaneProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.RemoveDataplaneProjectRequestSchema\u003e): Promise\u003cRemoveDataplaneProjectResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../dataplanes/01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.RemoveDataplaneProjectRequest{}\n\n\tresp, err := client.Admin().RemoveDataplaneProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/removedataplaneproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.RemoveDataplaneProjectRequest()\ntry:\n result = client.admin.remove_dataplane_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.removeDataplaneProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../dataplanes/01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/admin/v1/customers/{customer_id}/dataplanes/{dataplane_id}/projects/{project_id}","slug":"remove-dataplane-project"}
Delete dataplane
Changed in v0.7.0 (behaviour changes): Deleting a data plane now refuses while it is the only one serving a project, and the refusal names up to ten of those projects and reports how many there are in all. A data plane whose projects are all served by another one is deleted as before. Detaching a project from its last data plane is still allowed and now writes a PROJECT_SERVED_NOWHERE audit entry naming the project and that data plane, so the audit log carries a new action type from this release on.
Changed in v0.7.0 (new features): Forgetting a data plane now leaves a zeroize directive waiting for it and soft-deletes its credential. The directive travels only on the data plane's own next configuration poll, which the record shows as a call home, and the data plane acknowledges it like any configuration revision. A data plane that never calls keeps serving what it holds, and the forget can be undone until the directive lands. A data plane that was issued a new credential before it was forgotten collects its directive too.
What it does: Delete a data plane (soft delete).
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | undocumented |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | undocumented |
deleted_at | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) DeleteDataplane(ctx context.Context, req *adminv1.DeleteDataplaneRequest) (*adminv1.DeleteDataplaneResponse, error)","python":"delete_dataplane(req: admin_pb2.DeleteDataplaneRequest) -\u003e DeleteDataplaneResponse","typescript":"deleteDataplane(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.DeleteDataplaneRequestSchema\u003e): Promise\u003cDeleteDataplaneResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.DeleteDataplaneRequest{}\n\n\tresp, err := client.Admin().DeleteDataplane(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/deletedataplane\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.DeleteDataplaneRequest()\ntry:\n result = client.admin.delete_dataplane(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.deleteDataplane(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/admin/v1/dataplanes/{id}","slug":"delete-dataplane"}
List dataplane config overrides
Changed in v0.7.0 (behaviour changes): A provider endpoint or key override now applies to one project on a data plane and names that project, so another project the same data plane serves keeps calling the provider with the bundle endpoint and credential. An override written before this release named no project and is removed, with its stored credential, the first time the management plane starts after the upgrade.
Changed in v0.7.0 (new features): An administrator can now give one project on one data plane its own endpoint or its own key for one provider, and every other project that data plane serves goes on calling the provider with the bundle endpoint and credential. A key is write-only and reaches only the project it was written for; clearing an override restores the bundle value and destroys the key.
What it does: List the whitelisted overrides one data plane carries, for one project or for every project. A key override reports only that a credential is set: no read path on this service returns key material.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Server-generated data plane UUID, the id a Dataplane carries. The owning customer is the data plane's own, so the request names none. |
project_id | no | Narrows the list to one project. Empty lists every project's overrides. |
Response fields:
| Field | Required | Description |
|---|---|---|
overrides | no | The overrides this data plane carries, ordered by project and then by canonical field path. |
project_scoped | no | Always true from a management plane that keys overrides on the project. A caller reads it to tell that build from an older one, which ignores the request's project_id, lists overrides that reach every project on the data plane, and would store a write as one that reaches every project too. |
{"signatures":{"go":"func (x *AdminClient) ListDataplaneConfigOverrides(ctx context.Context, req *adminv1.ListDataplaneConfigOverridesRequest) (*adminv1.ListDataplaneConfigOverridesResponse, error)","python":"list_dataplane_config_overrides(req: admin_pb2.ListDataplaneConfigOverridesRequest) -\u003e ListDataplaneConfigOverridesResponse","typescript":"listDataplaneConfigOverrides(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListDataplaneConfigOverridesRequestSchema\u003e): Promise\u003cListDataplaneConfigOverridesResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../config-overrides\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListDataplaneConfigOverridesRequest{}\n\n\tresp, err := client.Admin().ListDataplaneConfigOverrides(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listdataplaneconfigoverrides\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListDataplaneConfigOverridesRequest()\ntry:\n result = client.admin.list_dataplane_config_overrides(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listDataplaneConfigOverrides(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../config-overrides\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/dataplanes/{id}/config-overrides","slug":"list-dataplane-config-overrides"}
Set dataplane config override
Changed in v0.11.0 (bug fixes): Changes that check a data plane's version, such as provider overrides, shared and catch-all hostnames, OIDC contracts and the newer rate-limit dimensions, no longer refuse a data plane on 0.11.0 or newer that was just upgraded or has had no configuration change for a day, because it now reports its version on every poll. A data plane silent for 24 hours is refused as down, disconnected or older than 0.11.0, with a prompt to check its connection and build.
Changed in v0.7.0 (behaviour changes): A provider endpoint or key override now applies to one project on a data plane and names that project, so another project the same data plane serves keeps calling the provider with the bundle endpoint and credential. An override written before this release named no project and is removed, with its stored credential, the first time the management plane starts after the upgrade.
Changed in v0.7.0 (new features): An administrator can now give one project on one data plane its own endpoint or its own key for one provider, and every other project that data plane serves goes on calling the provider with the bundle endpoint and credential. A key is write-only and reaches only the project it was written for; clearing an override restores the bundle value and destroys the key.
What it does: Override one whitelisted field on one data plane. Exactly one of value and key carries the override, and which one is decided by the field path: providers.<provider>.endpoint takes value, and providers.<provider>.key takes key. A field path outside the whitelist is rejected with INVALID_ARGUMENT naming the two paths a provider offers. A repeat write replaces the value the field held. Every write lands in the audit log with the field path, the data plane and the actor, and the data plane it names regenerates its configuration, so it carries the override on its next pull. A credential is stored write-only: it goes to the secret service and the override keeps a reference the data plane resolves, which resolves for that data plane alone. A write needs the project labelled on the data plane, and answers FAILED_PRECONDITION naming both when it is not: label the project onto the data plane first. A project that does not exist answers NOT_FOUND. A write to an external provider is refused for both fields, and a credential override for a provider whose auth type is none is refused, because a data plane never reads a credential for that provider. A data plane below the version that renders per-project provider objects is refused for both fields. An override reaches the project's requests on every route family the data plane serves it through: the shared catalog routes, the fallback chains and the routes of the project's own keys. A request authenticated with a key the caller brought themselves (BYOK) keeps dialling the bundle endpoint with the caller's key. On a deployment that registers an external autofallback-<provider> catalog entry, the primary leg routed through that service is not covered.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Server-generated data plane UUID, the id a Dataplane carries. The owning customer is the data plane's own, so the request names none. |
field_path | no | The whitelisted field, e.g. "providers.openai.endpoint". Case and provider spelling are normalized, so PROVIDERS.AWS-BEDROCK.ENDPOINT and providers.awsbedrock.endpoint name one field. |
value | no | The address to call the provider on, for an endpoint field. It carries a scheme, because the data plane decides TLS and the port from it. |
key | no | The credential, for a key field. Write-only: no read path returns it. |
project_id | no | The project the override applies to. It has to be labelled on the data plane. |
Response fields:
| Field | Required | Description |
|---|---|---|
override | no | The stored override, with a key reported as set rather than returned. |
{"signatures":{"go":"func (x *AdminClient) SetDataplaneConfigOverride(ctx context.Context, req *adminv1.SetDataplaneConfigOverrideRequest) (*adminv1.SetDataplaneConfigOverrideResponse, error)","python":"set_dataplane_config_override(req: admin_pb2.SetDataplaneConfigOverrideRequest) -\u003e SetDataplaneConfigOverrideResponse","typescript":"setDataplaneConfigOverride(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.SetDataplaneConfigOverrideRequestSchema\u003e): Promise\u003cSetDataplaneConfigOverrideResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../config-overrides\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"field_path\": \"...\",\n \"value\": \"...\",\n \"key\": \"...\",\n \"project_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.SetDataplaneConfigOverrideRequest{}\n\n\tresp, err := client.Admin().SetDataplaneConfigOverride(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/setdataplaneconfigoverride\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.SetDataplaneConfigOverrideRequest()\ntry:\n result = client.admin.set_dataplane_config_override(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.setDataplaneConfigOverride(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../config-overrides\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"field_path\": \"...\",\n \"value\": \"...\",\n \"key\": \"...\",\n \"project_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/dataplanes/{id}/config-overrides","slug":"set-dataplane-config-override"}
Clear dataplane config override
Changed in v0.7.0 (behaviour changes): A provider endpoint or key override now applies to one project on a data plane and names that project, so another project the same data plane serves keeps calling the provider with the bundle endpoint and credential. An override written before this release named no project and is removed, with its stored credential, the first time the management plane starts after the upgrade.
Changed in v0.7.0 (new features): An administrator can now give one project on one data plane its own endpoint or its own key for one provider, and every other project that data plane serves goes on calling the provider with the bundle endpoint and credential. A key is write-only and reaches only the project it was written for; clearing an override restores the bundle value and destroys the key.
What it does: Clear one project's override of one field, which returns the field to the value the bundle carries for that project. Clearing a field that carries no override reports cleared: false rather than failing. Clearing a credential override also destroys the stored credential, so the reference stops resolving for anyone. The project's requests fall back to the deployment-wide credential once the data plane applies its next pull, which an administrator containing a leaked key has to check is not the leaked one: a clear revokes nothing at the provider.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Server-generated data plane UUID, the id a Dataplane carries. The owning customer is the data plane's own, so the request names none. |
field_path | no | The whitelisted field to return to the bundle value. |
project_id | no | The project whose override is cleared. |
Response fields:
| Field | Required | Description |
|---|---|---|
cleared | no | False when the field carried no override, which is not an error. |
{"signatures":{"go":"func (x *AdminClient) ClearDataplaneConfigOverride(ctx context.Context, req *adminv1.ClearDataplaneConfigOverrideRequest) (*adminv1.ClearDataplaneConfigOverrideResponse, error)","python":"clear_dataplane_config_override(req: admin_pb2.ClearDataplaneConfigOverrideRequest) -\u003e ClearDataplaneConfigOverrideResponse","typescript":"clearDataplaneConfigOverride(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ClearDataplaneConfigOverrideRequestSchema\u003e): Promise\u003cClearDataplaneConfigOverrideResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../config-overrides:clear\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"field_path\": \"...\",\n \"project_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ClearDataplaneConfigOverrideRequest{}\n\n\tresp, err := client.Admin().ClearDataplaneConfigOverride(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/cleardataplaneconfigoverride\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ClearDataplaneConfigOverrideRequest()\ntry:\n result = client.admin.clear_dataplane_config_override(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.clearDataplaneConfigOverride(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../config-overrides:clear\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"field_path\": \"...\",\n \"project_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/dataplanes/{id}/config-overrides:clear","slug":"clear-dataplane-config-override"}
List dataplane config differences
Changed in v0.7.0 (new features): A data plane now reports each whitelisted field on which it serves something other than the bundle the management plane sent, with both values, and a project reports the fields its data planes disagree on. The management plane labels each difference as an intended override, as a data plane that has not pulled yet, or as one nothing explains. An administrator or the project's owner acknowledges a difference, and one that clears stays on record until then.
What it does: List the configuration differences one data plane reports.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Data plane id: the server-generated UUID this service returns as Dataplane.id, the same one every sibling RPC on this path space takes. Not Dataplane.dataplane_id, which is the slug an operator reads. |
include_cleared | no | Include the differences that have already cleared. They carry cleared_at, and they are how an operator sees that something was wrong after it stopped being wrong. |
include_acknowledged | no | Include the differences somebody has acknowledged. |
page_size | no | Max differences to return per page (0 = server default). The ledger keeps a cleared episode until somebody acknowledges it and the prune window passes, so a data plane with a long history of unanswered readings has an unbounded number of them and a whole-history response would grow with it. |
page_token | no | Opaque cursor from a previous response's next_page_token. |
Response fields:
| Field | Required | Description |
|---|---|---|
differences | no | The open, unacknowledged differences by default, newest first. |
next_page_token | no | Cursor for the next page; empty when there are no more results. |
{"signatures":{"go":"func (x *AdminClient) ListDataplaneConfigDifferences(ctx context.Context, req *adminv1.ListDataplaneConfigDifferencesRequest) (*adminv1.ListDataplaneConfigDifferencesResponse, error)","python":"list_dataplane_config_differences(req: admin_pb2.ListDataplaneConfigDifferencesRequest) -\u003e ListDataplaneConfigDifferencesResponse","typescript":"listDataplaneConfigDifferences(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListDataplaneConfigDifferencesRequestSchema\u003e): Promise\u003cListDataplaneConfigDifferencesResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../config-differences\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListDataplaneConfigDifferencesRequest{}\n\n\tresp, err := client.Admin().ListDataplaneConfigDifferences(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listdataplaneconfigdifferences\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListDataplaneConfigDifferencesRequest()\ntry:\n result = client.admin.list_dataplane_config_differences(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listDataplaneConfigDifferences(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/dataplanes/01H.../config-differences\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/dataplanes/{id}/config-differences","slug":"list-dataplane-config-differences"}
List project config differences
Changed in v0.7.0 (new features): A data plane now reports each whitelisted field on which it serves something other than the bundle the management plane sent, with both values, and a project reports the fields its data planes disagree on. The management plane labels each difference as an intended override, as a data plane that has not pulled yet, or as one nothing explains. An administrator or the project's owner acknowledges a difference, and one that clears stays on record until then.
What it does: List the fields the data planes serving one project disagree on.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | undocumented |
project_id | no | Project whose divergence record to read. Carries the project_id_field marker for resource-aware project_owner authz (gate amendment 5), the same as ListProjectGatewayMembers. The marker is what binds the gate to THIS field: the resolver falls back to a field conventionally named project_id, and the marker is what keeps that binding through a rename. |
include_cleared | no | undocumented |
include_acknowledged | no | undocumented |
page_size | no | Max differences to return per page (0 = server default). Bounded for the same reason the data plane read is: a project accumulates cleared episodes until they are acknowledged and pruned. |
page_token | no | Opaque cursor from a previous response's next_page_token. |
Response fields:
| Field | Required | Description |
|---|---|---|
differences | no | undocumented |
next_page_token | no | Cursor for the next page; empty when there are no more results. |
{"signatures":{"go":"func (x *AdminClient) ListProjectConfigDifferences(ctx context.Context, req *adminv1.ListProjectConfigDifferencesRequest) (*adminv1.ListProjectConfigDifferencesResponse, error)","python":"list_project_config_differences(req: admin_pb2.ListProjectConfigDifferencesRequest) -\u003e ListProjectConfigDifferencesResponse","typescript":"listProjectConfigDifferences(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectConfigDifferencesRequestSchema\u003e): Promise\u003cListProjectConfigDifferencesResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../config-differences\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectConfigDifferencesRequest{}\n\n\tresp, err := client.Admin().ListProjectConfigDifferences(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojectconfigdifferences\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectConfigDifferencesRequest()\ntry:\n result = client.admin.list_project_config_differences(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjectConfigDifferences(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../config-differences\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"App Developer (API key)","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/config-differences","slug":"list-project-config-differences"}
Acknowledge config difference
Changed in v0.7.0 (new features): A data plane now reports each whitelisted field on which it serves something other than the bundle the management plane sent, with both values, and a project reports the fields its data planes disagree on. The management plane labels each difference as an intended override, as a data plane that has not pulled yet, or as one nothing explains. An administrator or the project's owner acknowledges a difference, and one that clears stays on record until then.
What it does: Acknowledge one configuration difference, which takes it off the default view of the data plane or the project it reads on. The entry itself stays: nothing here deletes the record that the fleet was once split. Acknowledging an entry a second time changes nothing and reports acknowledged: false, so the ledger keeps naming whoever actually looked. A project owner answers the entries ListProjectConfigDifferences shows them by naming their project in project_id, which is what binds the gate to it. An administrator answers either list and leaves project_id empty.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | undocumented |
id | no | The difference to acknowledge, from either list. The acknowledgement casts it to uuid in SQL, so the same pattern every other uuid id on this service carries keeps a stale or hand-typed value an invalid_argument here rather than a cast error the handler can only report as internal. |
project_id | no | The project the entry reads on, for a project owner answering their own list. Naming it is what binds the gate to that project, and the entry has to be one of that project's own: an id belonging to a data plane, or to another project, comes back NOT_FOUND rather than acknowledged. An administrator leaves this empty and answers either list. min_len stays unset for that reason: an empty value is the administrator's case rather than a malformed one. |
Response fields:
| Field | Required | Description |
|---|---|---|
acknowledged | no | False when the difference was already acknowledged, which is not an error: the first acknowledgement stands and the ledger keeps naming whoever made it. That is the only thing false means. An id naming no entry the caller may answer -- one that never existed, one already pruned, or one on a data plane or another project when the caller named a project -- comes back NOT_FOUND instead, so a console can tell "somebody answered this" from "you cannot answer this". |
{"signatures":{"go":"func (x *AdminClient) AcknowledgeConfigDifference(ctx context.Context, req *adminv1.AcknowledgeConfigDifferenceRequest) (*adminv1.AcknowledgeConfigDifferenceResponse, error)","python":"acknowledge_config_difference(req: admin_pb2.AcknowledgeConfigDifferenceRequest) -\u003e AcknowledgeConfigDifferenceResponse","typescript":"acknowledgeConfigDifference(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.AcknowledgeConfigDifferenceRequestSchema\u003e): Promise\u003cAcknowledgeConfigDifferenceResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../config-differences/01H...:acknowledge\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.AcknowledgeConfigDifferenceRequest{}\n\n\tresp, err := client.Admin().AcknowledgeConfigDifference(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/acknowledgeconfigdifference\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.AcknowledgeConfigDifferenceRequest()\ntry:\n result = client.admin.acknowledge_config_difference(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.acknowledgeConfigDifference(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../config-differences/01H...:acknowledge\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\"\n }'"},"persona":"App Developer (API key)","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/config-differences/{id}:acknowledge","slug":"acknowledge-config-difference"}
Create project gateway
Changed in v0.11.0 (bug fixes): Changes that check a data plane's version, such as provider overrides, shared and catch-all hostnames, OIDC contracts and the newer rate-limit dimensions, no longer refuse a data plane on 0.11.0 or newer that was just upgraded or has had no configuration change for a day, because it now reports its version on every poll. A data plane silent for 24 hours is refused as down, disconnected or older than 0.11.0, with a prompt to check its connection and build.
Changed in v0.7.0 (behaviour changes): Once a data plane declares hostnames in its chart, these three calls accept only a hostname that data plane declared, and refuse anything else with FailedPrecondition naming the chart key. A data plane that has declared nothing keeps today's behaviour, so each one crosses over as its own chart lists a name. SetDataplaneURL no longer stamps a data plane's address onto its default gateway once that data plane declares its own hostnames; it still records the address itself, which is unchanged.
Changed in v0.7.0 (deprecations): Setting a data plane's or a project gateway's address through the admin API is deprecated. A 0.7 data plane reports its own address from global.gateway.hostnames in its serve-helm values. SetDataplaneURL, its SetWorkspaceURL alias, SetProjectGatewayURL and the url field of CreateProjectGateway and UpdateProjectGateway keep working. A data plane before 0.7 cannot declare hostnames, so these calls stay until no supported data plane predates 0.7.
Changed in v0.4.0 (security updates): Claiming a hostname that is already in use no longer exposes details about the existing configuration. The conflict message now says only that the hostname is in use, preventing a rejected claim from revealing information about another organization's resources.
What it does: Create project gateway
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Customer (tenant) slug that will own the project gateway. |
workspace_id | no | Owning dataplane (workspace) slug that hosts this project gateway. |
project_gateway_id | no | Caller-chosen project gateway slug, unique within the workspace. |
name | no | Optional human-readable display name. |
description | no | Optional free-text description. |
url | no | Optional customer-facing URL/hostname of this project gateway's ingress endpoint. Deprecated (fraser#8586): a data plane reports its own address from global.gateway.hostnames in its serve-helm values, and the management plane mirrors it read-only. This stays working in 0.6; removal is proposed for 0.8. |
labels | no | Optional user-defined key/value labels for organization/filtering. |
Response fields:
| Field | Required | Description |
|---|---|---|
project_gateway | no | The newly created project gateway. |
{"signatures":{"go":"func (x *AdminClient) CreateProjectGateway(ctx context.Context, req *adminv1.CreateProjectGatewayRequest) (*adminv1.CreateProjectGatewayResponse, error)","python":"create_project_gateway(req: admin_pb2.CreateProjectGatewayRequest) -\u003e CreateProjectGatewayResponse","typescript":"createProjectGateway(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.CreateProjectGatewayRequestSchema\u003e): Promise\u003cCreateProjectGatewayResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"workspace_id\": \"...\",\n \"project_gateway_id\": \"...\",\n \"name\": \"...\",\n \"description\": \"...\",\n \"url\": \"...\",\n \"labels\": {}\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.CreateProjectGatewayRequest{}\n\n\tresp, err := client.Admin().CreateProjectGateway(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/createprojectgateway\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.CreateProjectGatewayRequest()\ntry:\n result = client.admin.create_project_gateway(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.createProjectGateway(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"workspace_id\": \"...\",\n \"project_gateway_id\": \"...\",\n \"name\": \"...\",\n \"description\": \"...\",\n \"url\": \"...\",\n \"labels\": {}\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/project-gateways","slug":"create-project-gateway"}
List project gateways
Changed in v0.7.0 (new features): A project gateway can now declare the environment it serves in environment, and a gateway auth policy can name the token claim carrying a token's environment in environment_claim. Only a platform administrator can set or clear a gateway's environment, and an enabled policy with environment_claim is refused on a gateway that declares none. The gateway refuses an IdP token whose environment claim does not name the gateway's environment.
What it does: List project gateways (optionally filtered by customer, workspace, and/or attached project). Each returned gateway carries its attached project slugs in attached_project_ids, so reading gateway<->project attachments in bulk is ONE paginated request, not one ListProjectGatewayProjects call per gateway (#5591).
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Optional filter: only return project gateways owned by this customer slug. |
workspace_id | no | Optional filter: only return project gateways hosted by this workspace (dataplane). |
project_ids | no | Optional filter: only return project gateways that have at least one of these project slugs attached. Requires customer_id -- attachments are customer-scoped, so a bare slug filter would match across tenants. Filters on the same set attached_project_ids reports, and inherits its workspace caveat: one attachment matches every same-slug gateway the customer has, so this can return more than one gateway per project. Combined with the attached_project_ids returned on each gateway, this answers "which gateways serve these projects?" in ONE request instead of a ListProjectGateways call plus one ListProjectGatewayProjects call per gateway (#5591). Repeated fields get no CLI flag, so this filter is reachable over SDK and REST only, not tare api admin project-gateways list. |
page_size | no | Max project gateways to return per page (0 = server default). |
page_token | no | Opaque cursor from a previous response's next_page_token. |
Response fields:
| Field | Required | Description |
|---|---|---|
project_gateways | no | Page of matching project gateways. |
next_page_token | no | Cursor for the next page; empty when there are no more results. |
{"signatures":{"go":"func (x *AdminClient) ListProjectGateways(ctx context.Context, req *adminv1.ListProjectGatewaysRequest) (*adminv1.ListProjectGatewaysResponse, error)","python":"list_project_gateways(req: admin_pb2.ListProjectGatewaysRequest) -\u003e ListProjectGatewaysResponse","typescript":"listProjectGateways(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectGatewaysRequestSchema\u003e): Promise\u003cListProjectGatewaysResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectGatewaysRequest{}\n\n\tresp, err := client.Admin().ListProjectGateways(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojectgateways\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectGatewaysRequest()\ntry:\n result = client.admin.list_project_gateways(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjectGateways(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/project-gateways","slug":"list-project-gateways"}
Get project gateway
Changed in v0.7.0 (new features): A project gateway can now declare the environment it serves in environment, and a gateway auth policy can name the token claim carrying a token's environment in environment_claim. Only a platform administrator can set or clear a gateway's environment, and an enabled policy with environment_claim is refused on a gateway that declares none. The gateway refuses an IdP token whose environment claim does not name the gateway's environment.
What it does: Get project gateway
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Project gateway UUID (the internal id, not the customer-chosen project_gateway_id). |
project_id | no | Owner scope (#4637): when the caller is a project owner (not a platform admin), this is the project they own, and the handler verifies the gateway serves it. Ignored for admins. A project owner who omits this field is refused. |
Response fields:
| Field | Required | Description |
|---|---|---|
project_gateway | no | The requested project gateway. |
{"signatures":{"go":"func (x *AdminClient) GetProjectGateway(ctx context.Context, req *adminv1.GetProjectGatewayRequest) (*adminv1.GetProjectGatewayResponse, error)","python":"get_project_gateway(req: admin_pb2.GetProjectGatewayRequest) -\u003e GetProjectGatewayResponse","typescript":"getProjectGateway(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetProjectGatewayRequestSchema\u003e): Promise\u003cGetProjectGatewayResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetProjectGatewayRequest{}\n\n\tresp, err := client.Admin().GetProjectGateway(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getprojectgateway\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetProjectGatewayRequest()\ntry:\n result = client.admin.get_project_gateway(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getProjectGateway(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"App Developer (API key)","httpVerb":"GET","httpPath":"/admin/v1/project-gateways/{id}","slug":"get-project-gateway"}
Update project gateway
Changed in v0.7.0 (behaviour changes): Once a data plane declares hostnames in its chart, these three calls accept only a hostname that data plane declared, and refuse anything else with FailedPrecondition naming the chart key. A data plane that has declared nothing keeps today's behaviour, so each one crosses over as its own chart lists a name. SetDataplaneURL no longer stamps a data plane's address onto its default gateway once that data plane declares its own hostnames; it still records the address itself, which is unchanged.
Changed in v0.7.0 (new features): A project gateway can now declare the environment it serves in environment, and a gateway auth policy can name the token claim carrying a token's environment in environment_claim. Only a platform administrator can set or clear a gateway's environment, and an enabled policy with environment_claim is refused on a gateway that declares none. The gateway refuses an IdP token whose environment claim does not name the gateway's environment.
Changed in v0.7.0 (deprecations): Setting a data plane's or a project gateway's address through the admin API is deprecated. A 0.7 data plane reports its own address from global.gateway.hostnames in its serve-helm values. SetDataplaneURL, its SetWorkspaceURL alias, SetProjectGatewayURL and the url field of CreateProjectGateway and UpdateProjectGateway keep working. A data plane before 0.7 cannot declare hostnames, so these calls stay until no supported data plane predates 0.7.
Changed in v0.4.0 (security updates): Claiming a hostname that is already in use no longer exposes details about the existing configuration. The conflict message now says only that the hostname is in use, preventing a rejected claim from revealing information about another organization's resources.
What it does: Update project gateway
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Project gateway UUID to update. |
name | no | New display name; unset leaves the existing value. |
description | no | New description; unset leaves the existing value. |
url | no | New customer-facing URL/hostname; unset leaves the existing value. Deprecated (fraser#8586): a data plane reports its own address from global.gateway.hostnames in its serve-helm values, and the management plane mirrors it read-only. This stays working in 0.6; removal is proposed for 0.8. |
labels | no | Replacement set of labels. |
project_id | no | Owner scope (#4637): when the caller is a project owner (not a platform admin), this is the project they own; the handler verifies the gateway serves it. Ignored for admins. |
environment | no | The environment this gateway serves, against which the data plane compares a gateway auth policy's environment_claim (fraser#9288). The data plane refuses an IdP token whose claim does not name this environment, and refuses every token under a policy with environment_claim while the gateway declares none. Unset leaves the existing value, and an empty string clears it. A value is 1 to 63 characters, starts with a letter or digit, and holds only letters, digits, '.', '_' and '-', and it is stored exactly as written. Only a platform admin may set or clear it, and a project owner's request carrying the field is refused with PERMISSION_DENIED. That is because a gateway can serve several projects, and one project's owner would otherwise choose the environment every other project's tokens are checked against. Clearing it is refused with FAILED_PRECONDITION while an enabled gateway auth policy naming this gateway's slug sets environment_claim. |
Response fields:
| Field | Required | Description |
|---|---|---|
project_gateway | no | The updated project gateway. |
warnings | no | Non-fatal advisories surfaced when the update changes the gateway URL -- identical in meaning to SetProjectGatewayURLResponse.warnings (e.g. URL set but no project attached / no assigned models, so the gateway 404s until fixed). Empty when no URL was changed or the gateway is fully functional. |
{"signatures":{"go":"func (x *AdminClient) UpdateProjectGateway(ctx context.Context, req *adminv1.UpdateProjectGatewayRequest) (*adminv1.UpdateProjectGatewayResponse, error)","python":"update_project_gateway(req: admin_pb2.UpdateProjectGatewayRequest) -\u003e UpdateProjectGatewayResponse","typescript":"updateProjectGateway(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpdateProjectGatewayRequestSchema\u003e): Promise\u003cUpdateProjectGatewayResponse\u003e","curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"...\",\n \"description\": \"...\",\n \"url\": \"...\",\n \"labels\": {},\n \"project_id\": \"...\",\n \"environment\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpdateProjectGatewayRequest{}\n\n\tresp, err := client.Admin().UpdateProjectGateway(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/updateprojectgateway\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpdateProjectGatewayRequest()\ntry:\n result = client.admin.update_project_gateway(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.updateProjectGateway(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"...\",\n \"description\": \"...\",\n \"url\": \"...\",\n \"labels\": {},\n \"project_id\": \"...\",\n \"environment\": \"...\"\n }'"},"persona":"App Developer (API key)","httpVerb":"PATCH","httpPath":"/admin/v1/project-gateways/{id}","slug":"update-project-gateway"}
Delete project gateway
Changed in v0.11.0 (bug fixes): Changes that check a data plane's version, such as provider overrides, shared and catch-all hostnames, OIDC contracts and the newer rate-limit dimensions, no longer refuse a data plane on 0.11.0 or newer that was just upgraded or has had no configuration change for a day, because it now reports its version on every poll. A data plane silent for 24 hours is refused as down, disconnected or older than 0.11.0, with a prompt to check its connection and build.
Changed in v0.7.0 (deprecations): A project owner attaching a project to a gateway, detaching one or deleting a gateway is deprecated, and 0.9.0 requires a platform administrator for all three. Until then a project owner can make these changes while the gateway serves only projects they own. Once a gateway serves another owner's project, only a platform administrator can change it, and a project-owner credential answers 403.
What it does: Delete project gateway (soft delete)
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Project gateway UUID to soft-delete. |
project_id | no | Owner scope (#4637): when the caller is a project owner (not a platform admin), this is the project they own; the handler verifies the gateway serves it. Ignored for admins. |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the project gateway was deleted. |
deleted_at | no | When the soft delete took effect. |
{"signatures":{"go":"func (x *AdminClient) DeleteProjectGateway(ctx context.Context, req *adminv1.DeleteProjectGatewayRequest) (*adminv1.DeleteProjectGatewayResponse, error)","python":"delete_project_gateway(req: admin_pb2.DeleteProjectGatewayRequest) -\u003e DeleteProjectGatewayResponse","typescript":"deleteProjectGateway(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.DeleteProjectGatewayRequestSchema\u003e): Promise\u003cDeleteProjectGatewayResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.DeleteProjectGatewayRequest{}\n\n\tresp, err := client.Admin().DeleteProjectGateway(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/deleteprojectgateway\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.DeleteProjectGatewayRequest()\ntry:\n result = client.admin.delete_project_gateway(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.deleteProjectGateway(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"App Developer (API key)","httpVerb":"DELETE","httpPath":"/admin/v1/project-gateways/{id}","slug":"delete-project-gateway"}
Attach project gateway project
Changed in v0.11.0 (bug fixes): Changes that check a data plane's version, such as provider overrides, shared and catch-all hostnames, OIDC contracts and the newer rate-limit dimensions, no longer refuse a data plane on 0.11.0 or newer that was just upgraded or has had no configuration change for a day, because it now reports its version on every poll. A data plane silent for 24 hours is refused as down, disconnected or older than 0.11.0, with a prompt to check its connection and build.
Changed in v0.10.0 (behaviour changes): Writing a project's OIDC contract is refused on Agent Router Service (SaaS). Enabling a contract is refused while a data plane serving the project runs a build older than 0.10.0 or has not reported its build, and so is attaching a project whose contract is enabled to such a data plane. Each refusal names the data plane.
Changed in v0.9.0 (bug fixes): These changes are now audited: data plane changes made through the workspace API, guardrail pattern and fallback-policy changes, refused gateway attaches, data plane upgrade outcomes, and the data plane URL, token revocations and MCP catalog entries a data plane writes.
Changed in v0.9.0 (bug fixes): The warning for a gateway with no URL no longer says the gateway serves nothing. It now says the gateway serves through the catch-all while it is the only gateway on its data plane, and stops serving once another gateway joins.
Changed in v0.7.0 (behaviour changes): A project gateway now holds several projects. Attaching a second, different project used to be rejected with FailedPrecondition and a "detach the current project first" message; it now succeeds wherever the data plane can enforce the per-project boundary, so one hostname serves every project attached to its gateway and each request resolves to its own project by its own credential. Two concurrent attaches of the same project leave one of them with ABORTED, which the caller retries.
Changed in v0.7.0 (deprecations): A project owner attaching a project to a gateway, detaching one or deleting a gateway is deprecated, and 0.9.0 requires a platform administrator for all three. Until then a project owner can make these changes while the gateway serves only projects they own. Once a gateway serves another owner's project, only a platform administrator can change it, and a project-owner credential answers 403.
What it does: Attach a project to a project gateway (idempotent). Establishes a gateway<->project binding in the many-to-many project_gateway_projects relationship. A project gateway holds every project attached to it, so one hostname serves several projects and each request resolves to its own project by its own credential (fraser#9422). Re-attaching the same project is a no-op. Two concurrent attaches of the same binding leave one of them with ABORTED, which the caller retries. Ensure the attached project has assigned models BEFORE setting the gateway's URL: under strict isolation a gateway with no assigned models serves an EMPTY route map and will return 404 for every request. The response carries any such warnings in the warnings field. Multi-gateway projects (fraser#5987): a project may be attached to multiple gateways, capped per project (PROJECT_GATEWAY_CAP, default 10 on Enterprise; 1 on SaaS) — attaching beyond the cap is rejected with RESOURCE_EXHAUSTED (the cap is a quota, not a name collision; ALREADY_EXISTS stays reserved for hostname/slug uniqueness conflicts). The cap is a SOFT limit: the check is not atomic with the insert, so two concurrent attaches can both pass it and overshoot the cap by one. Attaching a gateway whose slug is shared with another live gateway is rejected with FAILED_PRECONDITION (rename or delete the sibling first). A successful attach starts the membership in the syncing state; see ListProjectGatewayMembers for the state machine.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Project gateway UUID to attach the project to. |
project_id | no | Project slug to bind to the project gateway. The project_id_field marker names the project this request targets, which is what confines a project-scoped management key to its own project: AuthorizeAPIKeyBoundary reads the marked field on every API-key credential short of platform admin, whatever scopes the RPC declares. The project_owner check reads it too, and the handler then checks every other project the gateway serves (#8590). |
Response fields:
| Field | Required | Description |
|---|---|---|
project_gateway | no | The project gateway the project was attached to. |
warnings | no | Non-fatal advisories about the attachment. Populated, for example, when the attached project has no assigned models -- the gateway will serve an empty route map (404s) until models are assigned. Empty when the attachment is fully functional. |
{"signatures":{"go":"func (x *AdminClient) AttachProjectGatewayProject(ctx context.Context, req *adminv1.AttachProjectGatewayProjectRequest) (*adminv1.AttachProjectGatewayProjectResponse, error)","python":"attach_project_gateway_project(req: admin_pb2.AttachProjectGatewayProjectRequest) -\u003e AttachProjectGatewayProjectResponse","typescript":"attachProjectGatewayProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.AttachProjectGatewayProjectRequestSchema\u003e): Promise\u003cAttachProjectGatewayProjectResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.AttachProjectGatewayProjectRequest{}\n\n\tresp, err := client.Admin().AttachProjectGatewayProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/attachprojectgatewayproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.AttachProjectGatewayProjectRequest()\ntry:\n result = client.admin.attach_project_gateway_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.attachProjectGatewayProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\"\n }'"},"persona":"App Developer (API key)","httpVerb":"POST","httpPath":"/admin/v1/project-gateways/{id}/projects","slug":"attach-project-gateway-project"}
Detach project gateway project
Changed in v0.7.0 (behaviour changes): Deleting a data plane now refuses while it is the only one serving a project, and the refusal names up to ten of those projects and reports how many there are in all. A data plane whose projects are all served by another one is deleted as before. Detaching a project from its last data plane is still allowed and now writes a PROJECT_SERVED_NOWHERE audit entry naming the project and that data plane, so the audit log carries a new action type from this release on.
Changed in v0.7.0 (bug fixes): Removing the last project from a data plane that has a single gateway now takes the project's label off, reports served_nowhere and records PROJECT_SERVED_NOWHERE in the audit log. Before, the call answered removed=true while the label stayed on the data plane, and neither was recorded.
Changed in v0.7.0 (deprecations): A project owner attaching a project to a gateway, detaching one or deleting a gateway is deprecated, and 0.9.0 requires a platform administrator for all three. Until then a project owner can make these changes while the gateway serves only projects they own. Once a gateway serves another owner's project, only a platform administrator can change it, and a project-owner credential answers 403.
What it does: Detach a project from a project gateway. Detach pushes a final zeroized config revision to the member (best-effort, DP-initiated polling) and revokes MP-side access as the authoritative backstop, so the membership lands in detached_unreachable until the data plane acknowledges the zero revision (then detached_zeroized). Detaching a project that is not attached is an idempotent no-op (success=false, no error). See ListProjectGatewayMembers for the state machine.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Project gateway UUID to detach the project from. |
project_id | no | Project slug to unbind from the project gateway. The project_id_field marker names the project this request targets, which is what confines a project-scoped management key to its own project: AuthorizeAPIKeyBoundary reads the marked field on every API-key credential short of platform admin, whatever scopes the RPC declares. The project_owner check reads it too, and the handler then checks every other project the gateway serves (#8590). |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the binding was removed. |
{"signatures":{"go":"func (x *AdminClient) DetachProjectGatewayProject(ctx context.Context, req *adminv1.DetachProjectGatewayProjectRequest) (*adminv1.DetachProjectGatewayProjectResponse, error)","python":"detach_project_gateway_project(req: admin_pb2.DetachProjectGatewayProjectRequest) -\u003e DetachProjectGatewayProjectResponse","typescript":"detachProjectGatewayProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.DetachProjectGatewayProjectRequestSchema\u003e): Promise\u003cDetachProjectGatewayProjectResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.DetachProjectGatewayProjectRequest{}\n\n\tresp, err := client.Admin().DetachProjectGatewayProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/detachprojectgatewayproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.DetachProjectGatewayProjectRequest()\ntry:\n result = client.admin.detach_project_gateway_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.detachProjectGatewayProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"App Developer (API key)","httpVerb":"DELETE","httpPath":"/admin/v1/project-gateways/{id}/projects/{project_id}","slug":"detach-project-gateway-project"}
Update project gateway project
Changed in v0.7.0 (new features): A project's membership of a project gateway now accepts ACCEPTED_CREDENTIALS_TOKEN on Enterprise, so the gateway refuses API keys for that project and accepts only IdP tokens. ACCEPTED_CREDENTIALS_BOTH no longer returns a warning. A data plane older than 0.7.0 keeps accepting API keys whatever the membership declares.
Changed in v0.6.0 (new features): Project gateway attachments now record accepted_credentials; existing attachments read API_KEY. Enterprise projects with an enabled jwt gateway auth policy can choose BOTH, which prevents disabling or deleting their last enabled policy. TOKEN is refused for now. The gateway does not yet enforce this setting: API keys still work, and an identity-provider token alone does not authenticate a caller.
What it does: Update a project's membership of a project gateway. The one mutable field is accepted_credentials, which says whether an Agent Router API key, a verified IdP token, or either one authenticates a caller of this project on this gateway (ADR 050, fraser#9834). A new attachment starts at ACCEPTED_CREDENTIALS_API_KEY, which is what every project did before the field existed. TOKEN and BOTH declare that the project accepts a credential verified at this gateway, so both are refused with FAILED_PRECONDITION while the project holds no enabled jwt gateway auth policy for this gateway, and disabling or deleting the project's last such policy is refused while the membership declares either one. Both are Enterprise-only, refused with FAILED_PRECONDITION on SaaS the way a jwt gateway auth policy is. The data plane enforces the declaration from release 0.7.0: it refuses an IdP token on a project declaring API_KEY, and an API key on a project declaring TOKEN. A data plane older than 0.7.0 authenticates API keys alone, whatever the declaration says. Returns NOT_FOUND when the project is not attached to this gateway.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Project gateway UUID the project is attached to. |
project_id | no | Attached project slug. Carries the project_id_field marker so resource-aware project_owner authz targets exactly this project. |
accepted_credentials | no | Which credentials authenticate a caller of this project on this gateway. |
Response fields:
| Field | Required | Description |
|---|---|---|
attachment | no | The membership as stored. |
warnings | no | Non-fatal advisories about the stored membership. Empty when there are none. |
{"signatures":{"go":"func (x *AdminClient) UpdateProjectGatewayProject(ctx context.Context, req *adminv1.UpdateProjectGatewayProjectRequest) (*adminv1.UpdateProjectGatewayProjectResponse, error)","python":"update_project_gateway_project(req: admin_pb2.UpdateProjectGatewayProjectRequest) -\u003e UpdateProjectGatewayProjectResponse","typescript":"updateProjectGatewayProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpdateProjectGatewayProjectRequestSchema\u003e): Promise\u003cUpdateProjectGatewayProjectResponse\u003e","curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"accepted_credentials\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpdateProjectGatewayProjectRequest{}\n\n\tresp, err := client.Admin().UpdateProjectGatewayProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/updateprojectgatewayproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpdateProjectGatewayProjectRequest()\ntry:\n result = client.admin.update_project_gateway_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.updateProjectGatewayProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"accepted_credentials\": \"...\"\n }'"},"persona":"App Developer (API key)","httpVerb":"PATCH","httpPath":"/admin/v1/project-gateways/{id}/projects/{project_id}","slug":"update-project-gateway-project"}
List project gateway projects
Changed in v0.6.0 (new features): Project gateway attachments now record accepted_credentials; existing attachments read API_KEY. Enterprise projects with an enabled jwt gateway auth policy can choose BOTH, which prevents disabling or deleting their last enabled policy. TOKEN is refused for now. The gateway does not yet enforce this setting: API keys still work, and an identity-provider token alone does not authenticate a caller.
What it does: List the project slugs attached to a project gateway.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Project gateway UUID whose attached projects are listed. |
Response fields:
| Field | Required | Description |
|---|---|---|
project_ids | no | Project slugs currently attached to the project gateway. |
attachments | no | The same attachments as project_ids, in the same order, each with the credentials the project accepts on this gateway. |
{"signatures":{"go":"func (x *AdminClient) ListProjectGatewayProjects(ctx context.Context, req *adminv1.ListProjectGatewayProjectsRequest) (*adminv1.ListProjectGatewayProjectsResponse, error)","python":"list_project_gateway_projects(req: admin_pb2.ListProjectGatewayProjectsRequest) -\u003e ListProjectGatewayProjectsResponse","typescript":"listProjectGatewayProjects(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectGatewayProjectsRequestSchema\u003e): Promise\u003cListProjectGatewayProjectsResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectGatewayProjectsRequest{}\n\n\tresp, err := client.Admin().ListProjectGatewayProjects(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojectgatewayprojects\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectGatewayProjectsRequest()\ntry:\n result = client.admin.list_project_gateway_projects(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjectGatewayProjects(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/project-gateways/{id}/projects","slug":"list-project-gateway-projects"}
List project gateway members
Changed in v0.7.0 (new features): A data plane now reports each whitelisted field on which it serves something other than the bundle the management plane sent, with both values, and a project reports the fields its data planes disagree on. The management plane labels each difference as an intended override, as a data plane that has not pulled yet, or as one nothing explains. An administrator or the project's owner acknowledges a difference, and one that clears stays on record until then.
Changed in v0.7.0 (new features): A project's gateway members now come back with where the project stands across the data planes serving it: the revision last minted for its configuration, how many labelled data planes have confirmed that revision, and how many carry the label at all. A member is one ingress endpoint and one data plane hosts several of them, so the two readings answer different questions and the rollup is the one that says whether the project is covered.
Changed in v0.6.0 (new features): Project gateway attachments now record accepted_credentials; existing attachments read API_KEY. Enterprise projects with an enabled jwt gateway auth policy can choose BOTH, which prevents disabling or deleting their last enabled policy. TOKEN is refused for now. The gateway does not yet enforce this setting: API keys still work, and an identity-provider token alone does not authenticate a caller.
What it does: List a project's member gateways with their membership state (D1 multi-gateway projects, fraser#5987 / ADR 052). This is the fleet-consistency primitive (epic tetrate-ai-platform#2865, gate amendment 6): for every member it reports the membership state machine position (syncing / ready / detached_zeroized / detached_unreachable), the member's last-acked config version vs. the project's head config version for that member, health (tri-state: unknown is a valid answer), last-seen, and the state timestamps. The shape is deliberately reusable by future consumers (D3 T1 steering, fleet-upgrade tooling): "is this fleet converged on config head?" is answerable per member from status + config_version + head_config_version alone. A member is advertised as ready ONLY under confirmed convergence: every per-gateway config slot acked by the data plane at its current version, PLUS the member workspace's shared PROXY (authz-map) slot when one exists (an absent workspace slot passes vacuously — the slot is minted on first authz-map generation). Because that PROXY slot is shared by every gateway in the workspace, a bump to it flips ALL of the workspace's members back to syncing until the new map version is acked — cross-member flap on workspace-slot bumps is expected behavior, not a defect. A previously-ready member whose project config moved ahead reports syncing again until the new head is acked. The config_version / head_config_version columns stay scoped to the member's own per-gateway slots (gateway family only): the workspace PROXY slot participates in the READY predicate but never in the version columns. Although marked NO_SIDE_EFFECTS, this read performs idempotent ledger reconciliation: attachments that predate the membership ledger are backfilled insert-only (a detached record is never reset by a list; only the Attach RPC does that). A legacy attachment backfilled this way gets a fabricated attached_at equal to the first list's server time — its true attach time was never recorded. A project with ZERO member gateways is fully valid: the response carries an empty members list (and whatever detached history exists), never an error. Responses carry NO credential material (gate amendment 5): identity, state, versions, and timestamps only. Enterprise only: on SaaS deployments (DEPLOYMENT_PRODUCT=saas) this RPC fails with UNIMPLEMENTED — the multi-gateway surface does not exist there (the existing attach/detach RPCs remain, capped at one gateway per project).
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project whose member gateways to list. Carries the project_id_field marker for resource-aware project_owner authz (gate amendment 5). |
Response fields:
| Field | Required | Description |
|---|---|---|
members | no | Live member gateways (attached; state SYNCING or READY). Empty for a zero-gateway project — a fully valid state, not an error. |
recently_detached | no | Detached membership records (state DETACHED_ZEROIZED or DETACHED_UNREACHABLE), most recently detached first, so operators can verify teardown after the member leaves the live list. Bounded: at most the 20 most recently detached records are returned; older history is retained in storage but not listed. |
gateway_cap | no | Effective per-project gateway cap for this deployment (PROJECT_GATEWAY_CAP, default 10 on Enterprise; 1 on SaaS). Attaching beyond it fails with RESOURCE_EXHAUSTED. The cap is a soft limit: the check is not atomic with the attach, so concurrent attaches can overshoot it by one. |
serving | no | Where the project stands across the DATA PLANES serving it, which the members list above cannot answer: a member is an ingress endpoint, and one data plane hosts many of them. Unset on a deployment whose readings are not available. |
diverging_field_count | no | How many whitelisted fields this project's data planes disagree on, which is the "data planes disagree (1 field)" badge on the project (tetrateio/fraser#8588). Zero when they hold the same configuration. An acknowledged difference still counts. Answering one does not make the data planes agree, and acknowledging an intended override is the commonest answer there is, so dropping it here would let this receipt report convergence for a project whose data planes call different provider addresses. |
differences | no | The differing fields with what explains each, acknowledged ones included for the same reason. A member list reporting convergence alone reads two data planes as identical while their effective configuration differs, so an intended difference is named here rather than suppressed. ListProjectConfigDifferences carries the values behind it. |
{"signatures":{"go":"func (x *AdminClient) ListProjectGatewayMembers(ctx context.Context, req *adminv1.ListProjectGatewayMembersRequest) (*adminv1.ListProjectGatewayMembersResponse, error)","python":"list_project_gateway_members(req: admin_pb2.ListProjectGatewayMembersRequest) -\u003e ListProjectGatewayMembersResponse","typescript":"listProjectGatewayMembers(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectGatewayMembersRequestSchema\u003e): Promise\u003cListProjectGatewayMembersResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../gateway-members\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectGatewayMembersRequest{}\n\n\tresp, err := client.Admin().ListProjectGatewayMembers(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojectgatewaymembers\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectGatewayMembersRequest()\ntry:\n result = client.admin.list_project_gateway_members(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjectGatewayMembers(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../gateway-members\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"App Developer (API key)","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/gateway-members","slug":"list-project-gateway-members"}
Set project gateway URL
Changed in v0.7.0 (behaviour changes): Once a data plane declares hostnames in its chart, these three calls accept only a hostname that data plane declared, and refuse anything else with FailedPrecondition naming the chart key. A data plane that has declared nothing keeps today's behaviour, so each one crosses over as its own chart lists a name. SetDataplaneURL no longer stamps a data plane's address onto its default gateway once that data plane declares its own hostnames; it still records the address itself, which is unchanged.
Changed in v0.7.0 (deprecations): Setting a data plane's or a project gateway's address through the admin API is deprecated. A 0.7 data plane reports its own address from global.gateway.hostnames in its serve-helm values. SetDataplaneURL, its SetWorkspaceURL alias, SetProjectGatewayURL and the url field of CreateProjectGateway and UpdateProjectGateway keep working. A data plane before 0.7 cannot declare hostnames, so these calls stay until no supported data plane predates 0.7.
Changed in v0.4.0 (security updates): Claiming a hostname that is already in use no longer exposes details about the existing configuration. The conflict message now says only that the hostname is in use, preventing a rejected claim from revealing information about another organization's resources.
Deprecated
What it does: Set the customer-facing URL/hostname for a project gateway. The hostname (host part of the URL) must be globally UNIQUE across all project gateways in the platform; setting a hostname already bound to a different gateway is rejected with ALREADY_EXISTS. Behavior change (strict isolation): once any gateway in a data plane's workspace has its URL set, that data plane serves ONLY per-gateway host-scoped routes -- the default all-models route is suppressed, so clients must call the gateway hostname rather than the workspace's shared URL. Best practice: attach a project and assign its models BEFORE setting the URL. Setting a URL on a gateway with no attached project (or whose project has no assigned models) makes the gateway reachable but it will return 404 for every request until a project with assigned models is attached. The response surfaces any such condition in the warnings field. Deprecated (fraser#8586): a data plane reports its own address from global.gateway.hostnames in its serve-helm values, and the management plane mirrors it read-only. This stays working in 0.6; removal is proposed for 0.8.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Project gateway UUID whose URL is being set. |
url | no | url is the customer-facing URL/hostname of the project gateway's ingress endpoint. Its host part must be globally unique across all project gateways (a hostname bound to another gateway is rejected with ALREADY_EXISTS). |
project_id | no | Owner scope (#4637): when the caller is a project owner (not a platform admin), this is the project they own; the handler verifies the gateway serves it. Ignored for admins. |
Response fields:
| Field | Required | Description |
|---|---|---|
project_gateway | no | The project gateway reflecting the new URL. |
warnings | no | Non-fatal advisories about the URL change. Populated, for example, when the gateway has no attached project (or its project has no assigned models) -- the gateway is now reachable but will return 404 for every request until a project with assigned models is attached. Empty when the gateway is fully functional. |
{"signatures":{"go":"func (x *AdminClient) SetProjectGatewayURL(ctx context.Context, req *adminv1.SetProjectGatewayURLRequest) (*adminv1.SetProjectGatewayURLResponse, error)","python":"set_project_gateway_url(req: admin_pb2.SetProjectGatewayURLRequest) -\u003e SetProjectGatewayURLResponse","typescript":"setProjectGatewayURL(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.SetProjectGatewayURLRequestSchema\u003e): Promise\u003cSetProjectGatewayURLResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../url\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"url\": \"...\",\n \"project_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.SetProjectGatewayURLRequest{}\n\n\tresp, err := client.Admin().SetProjectGatewayURL(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/setprojectgatewayurl\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.SetProjectGatewayURLRequest()\ntry:\n result = client.admin.set_project_gateway_url(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.setProjectGatewayURL(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../url\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"url\": \"...\",\n \"project_id\": \"...\"\n }'"},"persona":"App Developer (API key)","httpVerb":"POST","httpPath":"/admin/v1/project-gateways/{id}/url","slug":"set-project-gateway-url"}
Set project gateway workspace
Changed in v0.11.0 (bug fixes): Changes that check a data plane's version, such as provider overrides, shared and catch-all hostnames, OIDC contracts and the newer rate-limit dimensions, no longer refuse a data plane on 0.11.0 or newer that was just upgraded or has had no configuration change for a day, because it now reports its version on every poll. A data plane silent for 24 hours is refused as down, disconnected or older than 0.11.0, with a prompt to check its connection and build.
Changed in v0.9.0 (bug fixes): The warning for a gateway with no URL no longer says the gateway serves nothing. It now says the gateway serves through the catch-all while it is the only gateway on its data plane, and stops serving once another gateway joins.
What it does: Reassign a project gateway to a different dataplane (workspace). A data plane serves ONLY the hostnames of project gateways whose workspace_id matches its own (via per-gateway host-scoped routes plus the P10 authz map). Moving a gateway is therefore NOT a bare DB flip: this RPC tears down the gateway's per-gateway routes + authz binding on the OLD data plane and materializes them on the NEW one, refreshing both workspaces' authz maps and default-route suppression. The gateway's hostname is unchanged, so DNS is NOT moved automatically: the hostname still resolves to the OLD data plane's ingress until an operator repoints it. Until that cutover, requests to the hostname hit the old data plane (now torn down) and 404. The response ALWAYS includes a warnings entry reminding the operator to repoint DNS (and provision the new data plane's TLS cert). Recommended order: provision the new data plane's DNS/cert, call this RPC, then cut DNS over. Reassigning to the gateway's current workspace is a no-op. The new workspace must exist for the gateway's customer, and the gateway's slug must be free in the new workspace (a collision is rejected with ALREADY_EXISTS).
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Project gateway UUID to reassign. |
workspace_id | no | Target dataplane (workspace) slug to move the project gateway to. Must exist for the gateway's customer, and the gateway's slug must be free in it. |
Response fields:
| Field | Required | Description |
|---|---|---|
project_gateway | no | The project gateway reflecting the new workspace. |
warnings | no | Non-fatal advisories about the move. ALWAYS includes a reminder that the gateway's hostname is unchanged and must be repointed (DNS + TLS cert) to the new dataplane's ingress, or traffic will 404 on the old dataplane until cutover. May also carry the same no-project / no-models / no-URL advisories as SetProjectGatewayURL when the gateway is not yet fully functional. |
{"signatures":{"go":"func (x *AdminClient) SetProjectGatewayWorkspace(ctx context.Context, req *adminv1.SetProjectGatewayWorkspaceRequest) (*adminv1.SetProjectGatewayWorkspaceResponse, error)","python":"set_project_gateway_workspace(req: admin_pb2.SetProjectGatewayWorkspaceRequest) -\u003e SetProjectGatewayWorkspaceResponse","typescript":"setProjectGatewayWorkspace(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.SetProjectGatewayWorkspaceRequestSchema\u003e): Promise\u003cSetProjectGatewayWorkspaceResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../workspace\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspace_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.SetProjectGatewayWorkspaceRequest{}\n\n\tresp, err := client.Admin().SetProjectGatewayWorkspace(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/setprojectgatewayworkspace\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.SetProjectGatewayWorkspaceRequest()\ntry:\n result = client.admin.set_project_gateway_workspace(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.setProjectGatewayWorkspace(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/project-gateways/01H.../workspace\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"workspace_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/project-gateways/{id}/workspace","slug":"set-project-gateway-workspace"}
Create service account
Changed in v0.8.0 (security updates): SetWorkspaceURL and SetDataplaneURL refuse to set or clear a data plane URL with FailedPrecondition when another organization uses the same data plane ID. The URL was stored under the ID alone, so the write also changed the other organization's data plane. CreateServiceAccount with a serve URL for such an ID is refused too when no URL is stored for that ID yet. The Admin Console's System Settings save does not check this yet; it moves onto SetDataplaneURL in a later release.
Changed in v0.1.5 (bug fixes): Creating or revoking a service account now takes effect in seconds rather than minutes. The published key set is refreshed immediately by the instance handling the change and within 30 seconds elsewhere, where previously either could take up to five minutes, long enough that a new service account was rejected as if its credentials were wrong, and a revoked one kept being accepted.
What it does: Create service account
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Customer slug the service account belongs to. |
workspace_id | no | Workspace slug the service account is scoped to. |
validity_days | no | How many days the generated credential stays valid (default applied if unset). |
api_uri | no | Management-plane API base URI embedded in the service account. |
serve_url | no | Customer-facing data-plane serve URL embedded in the service account. |
issuer | no | JWT issuer (iss) to embed in the auth-server config. |
audience | no | JWT audience (aud) to embed in the auth-server config. |
jwks_uri | no | JWKS endpoint URI for verifying tokens issued to this account. |
telemetry_endpoint | no | OTLP exporter endpoint for telemetry export. |
telemetry_protocol | no | OTLP wire protocol: grpc, http/protobuf, or http/json. |
telemetry_insecure | no | If true, skip TLS verification for the telemetry endpoint. |
telemetry_timeout | no | OTLP export timeout as a Go duration (e.g. "10s"). |
telemetry_headers | no | Extra headers attached to telemetry exports (e.g. auth tokens). |
scopes | no | OAuth-style scopes granted to the service account. |
router_url | no | Optional: Router configuration to include in generated service account. When providing router_key this may be either a plaintext key (the server will store it in the configured secret manager and replace with a secret ref) or a secret reference (e.g. noop://..., sm://..., arn:aws:...). |
router_key | no | undocumented |
internal_api_key | no | Optional: Internal API key for dataplane → management plane authentication. In production (DB mode): Must be a secret reference (e.g., projects/.../secrets/internal-api-key-...). Generated offline via admin CLI and stored in remote Secret Manager (GCP/AWS). In file mode: Can be plaintext for local development. Typically per-customer (one key shared by all service accounts for the customer). |
telemetry_local_vars | no | Optional: Local OTEL environment variable overrides to embed in the service account. Values may be plaintext or secret references (e.g., sm://project/secret, noop://name). The server resolves any secret references via the configured secret manager and re-stores them as valet:// references before embedding in the generated service account. The dataplane resolves valet:// references at load time so initLocalDestination sees plaintext values when constructing the OTEL exporter. Example: {"OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer sm://myproject/otlp-token"} |
roles | no | Optional: built-in role slugs to bind this service account to at creation (fraser#5714). Each becomes an org-scoped rbac_binding on the SA principal, so the SA's calls resolve through RBAC — e.g. "internal" for a data-plane worker, whose control-loop callbacks then no longer need the coarse admin scope. Unknown or not-yet-seeded roles are skipped; binding is best-effort and never fails service-account creation. |
Response fields:
| Field | Required | Description |
|---|---|---|
service_account | no | The generated service account, including the private key (returned only here). |
checksum | no | Integrity checksum over the canonical service-account JSON. |
checksum_algorithm | no | Hash algorithm used for checksum (e.g. "sha256"). |
{"signatures":{"go":"func (x *AdminClient) CreateServiceAccount(ctx context.Context, req *adminv1.CreateServiceAccountRequest) (*adminv1.CreateServiceAccountResponse, error)","python":"create_service_account(req: admin_pb2.CreateServiceAccountRequest) -\u003e CreateServiceAccountResponse","typescript":"createServiceAccount(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.CreateServiceAccountRequestSchema\u003e): Promise\u003cCreateServiceAccountResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/service-accounts\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"workspace_id\": \"...\",\n \"validity_days\": 0,\n \"api_uri\": \"...\",\n \"serve_url\": \"...\",\n \"issuer\": \"...\",\n \"audience\": \"...\",\n \"jwks_uri\": \"...\",\n \"telemetry_endpoint\": \"...\",\n \"telemetry_protocol\": \"...\",\n \"telemetry_insecure\": false,\n \"telemetry_timeout\": \"...\",\n \"telemetry_headers\": {},\n \"scopes\": [],\n \"router_url\": \"...\",\n \"router_key\": \"...\",\n \"internal_api_key\": \"...\",\n \"telemetry_local_vars\": {},\n \"roles\": []\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.CreateServiceAccountRequest{}\n\n\tresp, err := client.Admin().CreateServiceAccount(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/createserviceaccount\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.CreateServiceAccountRequest()\ntry:\n result = client.admin.create_service_account(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.createServiceAccount(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/service-accounts\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"workspace_id\": \"...\",\n \"validity_days\": 0,\n \"api_uri\": \"...\",\n \"serve_url\": \"...\",\n \"issuer\": \"...\",\n \"audience\": \"...\",\n \"jwks_uri\": \"...\",\n \"telemetry_endpoint\": \"...\",\n \"telemetry_protocol\": \"...\",\n \"telemetry_insecure\": false,\n \"telemetry_timeout\": \"...\",\n \"telemetry_headers\": {},\n \"scopes\": [],\n \"router_url\": \"...\",\n \"router_key\": \"...\",\n \"internal_api_key\": \"...\",\n \"telemetry_local_vars\": {},\n \"roles\": []\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/service-accounts","slug":"create-service-account"}
List service accounts
What it does: List service accounts
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Optional filter by owning customer slug. |
workspace_id | no | Optional filter by workspace slug. |
status | no | Optional filter by account status. |
page_size | no | Max results per page (0 = server default). |
page_token | no | Opaque pagination cursor from a prior response. |
Response fields:
| Field | Required | Description |
|---|---|---|
service_accounts | no | Page of service account summaries (no private keys). |
next_page_token | no | Cursor for the next page; empty when exhausted. |
{"signatures":{"go":"func (x *AdminClient) ListServiceAccounts(ctx context.Context, req *adminv1.ListServiceAccountsRequest) (*adminv1.ListServiceAccountsResponse, error)","python":"list_service_accounts(req: admin_pb2.ListServiceAccountsRequest) -\u003e ListServiceAccountsResponse","typescript":"listServiceAccounts(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListServiceAccountsRequestSchema\u003e): Promise\u003cListServiceAccountsResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/service-accounts\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListServiceAccountsRequest{}\n\n\tresp, err := client.Admin().ListServiceAccounts(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listserviceaccounts\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListServiceAccountsRequest()\ntry:\n result = client.admin.list_service_accounts(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listServiceAccounts(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/service-accounts\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/service-accounts","slug":"list-service-accounts"}
Get service account
What it does: Get service account
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Service account UUID to fetch. |
Response fields:
| Field | Required | Description |
|---|---|---|
service_account | no | The requested service account summary. |
{"signatures":{"go":"func (x *AdminClient) GetServiceAccount(ctx context.Context, req *adminv1.GetServiceAccountRequest) (*adminv1.GetServiceAccountResponse, error)","python":"get_service_account(req: admin_pb2.GetServiceAccountRequest) -\u003e GetServiceAccountResponse","typescript":"getServiceAccount(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetServiceAccountRequestSchema\u003e): Promise\u003cGetServiceAccountResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/service-accounts/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetServiceAccountRequest{}\n\n\tresp, err := client.Admin().GetServiceAccount(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getserviceaccount\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetServiceAccountRequest()\ntry:\n result = client.admin.get_service_account(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getServiceAccount(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/service-accounts/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/service-accounts/{id}","slug":"get-service-account"}
Revoke service account
Changed in v0.1.5 (bug fixes): Creating or revoking a service account now takes effect in seconds rather than minutes. The published key set is refreshed immediately by the instance handling the change and within 30 seconds elsewhere, where previously either could take up to five minutes, long enough that a new service account was rejected as if its credentials were wrong, and a revoked one kept being accepted.
What it does: Revoke service account
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Service account UUID to revoke. |
reason | no | Optional human-readable revocation reason (audit trail). |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the account was revoked. |
revoked_at | no | When the revocation took effect. |
{"signatures":{"go":"func (x *AdminClient) RevokeServiceAccount(ctx context.Context, req *adminv1.RevokeServiceAccountRequest) (*adminv1.RevokeServiceAccountResponse, error)","python":"revoke_service_account(req: admin_pb2.RevokeServiceAccountRequest) -\u003e RevokeServiceAccountResponse","typescript":"revokeServiceAccount(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.RevokeServiceAccountRequestSchema\u003e): Promise\u003cRevokeServiceAccountResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/service-accounts/01H...:revoke\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"reason\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.RevokeServiceAccountRequest{}\n\n\tresp, err := client.Admin().RevokeServiceAccount(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/revokeserviceaccount\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.RevokeServiceAccountRequest()\ntry:\n result = client.admin.revoke_service_account(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.revokeServiceAccount(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/service-accounts/01H...:revoke\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"reason\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/service-accounts/{id}:revoke","slug":"revoke-service-account"}
Restore service account
What it does: Restore service account Restores a revoked service account to active status. Only one active service account per customer_id + workspace_id is allowed.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Service account UUID to restore to active. |
reason | no | Optional human-readable restore reason (audit trail). |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the account was restored. |
service_account | no | The restored account summary. |
{"signatures":{"go":"func (x *AdminClient) RestoreServiceAccount(ctx context.Context, req *adminv1.RestoreServiceAccountRequest) (*adminv1.RestoreServiceAccountResponse, error)","python":"restore_service_account(req: admin_pb2.RestoreServiceAccountRequest) -\u003e RestoreServiceAccountResponse","typescript":"restoreServiceAccount(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.RestoreServiceAccountRequestSchema\u003e): Promise\u003cRestoreServiceAccountResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/service-accounts/01H...:restore\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"reason\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.RestoreServiceAccountRequest{}\n\n\tresp, err := client.Admin().RestoreServiceAccount(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/restoreserviceaccount\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.RestoreServiceAccountRequest()\ntry:\n result = client.admin.restore_service_account(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.restoreServiceAccount(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/service-accounts/01H...:restore\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"reason\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/service-accounts/{id}:restore","slug":"restore-service-account"}
Create user token
Changed in v0.8.0 (bug fixes): Adding or removing a model from a project now updates keys that carry their own settings (BYOK, fallback, traffic split, or a rate limit), so they no longer keep routing against the old model list. A key created with CreateApiKey or IssueMyKey now gets its own routes instead of waiting on an unrelated change. Both updates are sent in the background, so the call returns without waiting for them.
Changed in v0.4.0 (bug fixes): Creating or rotating a routing key through the API saves the key and its client membership together. If membership setup fails, no partial key or client records remain. Newly created standalone routing keys also appear in the client list; those created directly through the token API have no client title.
Changed in v0.3.0 (bug fixes): Creating an API key now schedules a budget snapshot refresh instead of waiting for the next periodic rebuild, up to five minutes by default. Exhausted budgets begin enforcing on the new key once the updated snapshot reaches the data plane. The refresh runs in the background; it does not delay key creation.
What it does: Create user token Generates a JWT token for user authentication with gatekeeper.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Customer ID (e.g., "acme", "default") |
workspace_id | no | Workspace ID (e.g., "production", "staging", "internal") |
user_id | no | User ID from authentication provider (opaque identifier) |
role | no | User role from authentication (e.g., "developer", "admin") |
organization_unit | no | Organization unit from authentication (e.g., "engineering", "sales") |
expires_in_days | no | Token lifetime in days (default applied if unset). |
scopes | no | OAuth-style scopes embedded in the issued token. |
name | no | Optional human-readable name for the token |
impersonate | no | If true, the token will not be persisted to the database. This is used for impersonation scenarios where the token is temporary. |
impersonation_metadata | no | Optional metadata for impersonation tracking. When impersonate=true, this should contain the original user/admin who is impersonating. |
project_id | no | Project the key is scoped to within customer_id. Unset means the "default" project; for a non-default project the subject user must be a member (#4479). When set it is also embedded as the inference token's "project" claim so the dataplane stamps the internal x-project-id egress header without a key->project lookup (#4637). |
Response fields:
| Field | Required | Description |
|---|---|---|
access_token | no | The signed JWT to use as a bearer credential. |
token_type | no | Token type, typically "Bearer". |
expires_in | no | Seconds until the token expires. |
expires_at | no | Absolute expiry timestamp. |
jti | output-only | JWT ID (jti); used to look up and revoke the token. |
key_prefix | no | Database storage identifiers (for internal use) |
key_hash | no | undocumented |
key_address | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) CreateUserToken(ctx context.Context, req *adminv1.CreateUserTokenRequest) (*adminv1.CreateUserTokenResponse, error)","python":"create_user_token(req: admin_pb2.CreateUserTokenRequest) -\u003e CreateUserTokenResponse","typescript":"createUserToken(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.CreateUserTokenRequestSchema\u003e): Promise\u003cCreateUserTokenResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/user-tokens\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"workspace_id\": \"...\",\n \"user_id\": \"...\",\n \"role\": \"...\",\n \"organization_unit\": \"...\",\n \"expires_in_days\": 0,\n \"scopes\": [],\n \"name\": \"...\",\n \"impersonate\": false,\n \"impersonation_metadata\": {},\n \"project_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.CreateUserTokenRequest{}\n\n\tresp, err := client.Admin().CreateUserToken(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/createusertoken\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.CreateUserTokenRequest()\ntry:\n result = client.admin.create_user_token(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.createUserToken(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/user-tokens\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"workspace_id\": \"...\",\n \"user_id\": \"...\",\n \"role\": \"...\",\n \"organization_unit\": \"...\",\n \"expires_in_days\": 0,\n \"scopes\": [],\n \"name\": \"...\",\n \"impersonate\": false,\n \"impersonation_metadata\": {},\n \"project_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/user-tokens","slug":"create-user-token"}
List user tokens
Changed in v0.11.0 (behaviour changes): A disabled user token now shows the new DISABLED status, and the active filter no longer returns it. It was shown as active even though the data plane does not route it. A token that is both disabled and revoked or expired still shows REVOKED or EXPIRED. ListUserTokens takes a new disabled status filter that returns disabled tokens that are neither revoked nor expired; filter by revoked or expired to find the others.
Changed in v0.2.0 (security updates): Listing, reading and revoking user tokens through the admin API is now confined to the calling credential's own organization. A credential carrying the broad admin scope could previously act on any organization's tokens, because these operations matched a token by its id alone and never checked who was asking. Naming a different organization on the request is refused. Credentials that are not tied to an organization, such as an operator's environment-configured key, are unaffected. An organization administrator signed in to the dashboard can now list, read and revoke their own organization's tokens through these operations, which an organization-scoped API key still cannot do. Before upgrading a management plane that serves more than one organization, re-scope by hand any user tokens still stamped with the placeholder organization "default": until you do, the organization that owns them can no longer read or revoke them.
What it does: List user tokens
Request fields:
| Field | Required | Description |
|---|---|---|
user_id | no | Optional filter by issuing user ID. |
status | no | Optional filter by token status. |
page_size | no | Max results per page (0 = server default). |
page_token | no | Opaque pagination cursor from a prior response. |
customer_id | no | Customer that owns the token. Optional for compatibility: a credential bound to a customer is confined to it whether or not this is set, and naming a different customer is denied. |
Response fields:
| Field | Required | Description |
|---|---|---|
tokens | no | Page of user token summaries. |
next_page_token | no | Cursor for the next page; empty when exhausted. |
{"signatures":{"go":"func (x *AdminClient) ListUserTokens(ctx context.Context, req *adminv1.ListUserTokensRequest) (*adminv1.ListUserTokensResponse, error)","python":"list_user_tokens(req: admin_pb2.ListUserTokensRequest) -\u003e ListUserTokensResponse","typescript":"listUserTokens(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListUserTokensRequestSchema\u003e): Promise\u003cListUserTokensResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/user-tokens\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListUserTokensRequest{}\n\n\tresp, err := client.Admin().ListUserTokens(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listusertokens\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListUserTokensRequest()\ntry:\n result = client.admin.list_user_tokens(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listUserTokens(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/user-tokens\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/user-tokens","slug":"list-user-tokens"}
Get user token
Changed in v0.11.0 (behaviour changes): A disabled user token now shows the new DISABLED status, and the active filter no longer returns it. It was shown as active even though the data plane does not route it. A token that is both disabled and revoked or expired still shows REVOKED or EXPIRED. ListUserTokens takes a new disabled status filter that returns disabled tokens that are neither revoked nor expired; filter by revoked or expired to find the others.
Changed in v0.2.0 (security updates): Listing, reading and revoking user tokens through the admin API is now confined to the calling credential's own organization. A credential carrying the broad admin scope could previously act on any organization's tokens, because these operations matched a token by its id alone and never checked who was asking. Naming a different organization on the request is refused. Credentials that are not tied to an organization, such as an operator's environment-configured key, are unaffected. An organization administrator signed in to the dashboard can now list, read and revoke their own organization's tokens through these operations, which an organization-scoped API key still cannot do. Before upgrading a management plane that serves more than one organization, re-scope by hand any user tokens still stamped with the placeholder organization "default": until you do, the organization that owns them can no longer read or revoke them.
What it does: Get user token
Request fields:
| Field | Required | Description |
|---|---|---|
jti | no | JWT ID (jti) of the token to fetch. |
customer_id | no | Customer that owns the token. Optional for compatibility: a credential bound to a customer is confined to it whether or not this is set, and naming a different customer is denied. |
Response fields:
| Field | Required | Description |
|---|---|---|
token | no | The requested token summary. |
{"signatures":{"go":"func (x *AdminClient) GetUserToken(ctx context.Context, req *adminv1.GetUserTokenRequest) (*adminv1.GetUserTokenResponse, error)","python":"get_user_token(req: admin_pb2.GetUserTokenRequest) -\u003e GetUserTokenResponse","typescript":"getUserToken(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetUserTokenRequestSchema\u003e): Promise\u003cGetUserTokenResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/user-tokens/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetUserTokenRequest{}\n\n\tresp, err := client.Admin().GetUserToken(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getusertoken\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetUserTokenRequest()\ntry:\n result = client.admin.get_user_token(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getUserToken(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/user-tokens/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/user-tokens/{jti}","slug":"get-user-token"}
Revoke user token
Changed in v0.2.0 (security updates): Listing, reading and revoking user tokens through the admin API is now confined to the calling credential's own organization. A credential carrying the broad admin scope could previously act on any organization's tokens, because these operations matched a token by its id alone and never checked who was asking. Naming a different organization on the request is refused. Credentials that are not tied to an organization, such as an operator's environment-configured key, are unaffected. An organization administrator signed in to the dashboard can now list, read and revoke their own organization's tokens through these operations, which an organization-scoped API key still cannot do. Before upgrading a management plane that serves more than one organization, re-scope by hand any user tokens still stamped with the placeholder organization "default": until you do, the organization that owns them can no longer read or revoke them.
What it does: Revoke user token Revokes a user token by its JTI (JWT ID).
Request fields:
| Field | Required | Description |
|---|---|---|
jti | no | JWT ID (jti) of the token to revoke. |
reason | no | Optional human-readable revocation reason (audit trail). |
customer_id | no | Customer that owns the token. Optional for compatibility: a credential bound to a customer is confined to it whether or not this is set, and naming a different customer is denied. |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the token was revoked. |
revoked_at | no | When the revocation took effect. |
{"signatures":{"go":"func (x *AdminClient) RevokeUserToken(ctx context.Context, req *adminv1.RevokeUserTokenRequest) (*adminv1.RevokeUserTokenResponse, error)","python":"revoke_user_token(req: admin_pb2.RevokeUserTokenRequest) -\u003e RevokeUserTokenResponse","typescript":"revokeUserToken(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.RevokeUserTokenRequestSchema\u003e): Promise\u003cRevokeUserTokenResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/user-tokens/01H...:revoke\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"reason\": \"...\",\n \"customer_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.RevokeUserTokenRequest{}\n\n\tresp, err := client.Admin().RevokeUserToken(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/revokeusertoken\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.RevokeUserTokenRequest()\ntry:\n result = client.admin.revoke_user_token(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.revokeUserToken(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/user-tokens/01H...:revoke\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"reason\": \"...\",\n \"customer_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/user-tokens/{jti}:revoke","slug":"revoke-user-token"}
Create telemetry config
What it does: Create telemetry config
Request fields:
| Field | Required | Description |
|---|---|---|
user_id | no | Owner of the forwarding config. |
telemetry_type | no | Signal type to forward: traces, metrics, logs, or audit_logs. |
sink_url | no | Destination OTLP sink URL. |
protocol | no | OTLP wire protocol for the sink. |
auth_type | no | Authentication scheme for the sink. |
auth_value | no | undocumented |
api_key_header | no | Header name to carry the key when auth_type is api_key. |
enabled | no | Whether forwarding starts enabled (default enabled if unset). |
forward_interval_seconds | no | Audit-log forward interval in seconds (default 300 if unset). |
Response fields:
| Field | Required | Description |
|---|---|---|
config | no | The created forwarding config (auth_value decrypted). |
{"signatures":{"go":"func (x *AdminClient) CreateTelemetryConfig(ctx context.Context, req *adminv1.CreateTelemetryConfigRequest) (*adminv1.CreateTelemetryConfigResponse, error)","python":"create_telemetry_config(req: admin_pb2.CreateTelemetryConfigRequest) -\u003e CreateTelemetryConfigResponse","typescript":"createTelemetryConfig(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.CreateTelemetryConfigRequestSchema\u003e): Promise\u003cCreateTelemetryConfigResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"user_id\": \"...\",\n \"telemetry_type\": \"...\",\n \"sink_url\": \"...\",\n \"protocol\": \"...\",\n \"auth_type\": \"...\",\n \"auth_value\": \"...\",\n \"api_key_header\": \"...\",\n \"enabled\": false,\n \"forward_interval_seconds\": 0\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.CreateTelemetryConfigRequest{}\n\n\tresp, err := client.Admin().CreateTelemetryConfig(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/createtelemetryconfig\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.CreateTelemetryConfigRequest()\ntry:\n result = client.admin.create_telemetry_config(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.createTelemetryConfig(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"user_id\": \"...\",\n \"telemetry_type\": \"...\",\n \"sink_url\": \"...\",\n \"protocol\": \"...\",\n \"auth_type\": \"...\",\n \"auth_value\": \"...\",\n \"api_key_header\": \"...\",\n \"enabled\": false,\n \"forward_interval_seconds\": 0\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/telemetry-configs","slug":"create-telemetry-config"}
List telemetry configs
What it does: List telemetry configs
Request fields:
| Field | Required | Description |
|---|---|---|
user_id | no | undocumented |
telemetry_type | no | Optional filter by signal type. |
enabled | no | undocumented |
Response fields:
| Field | Required | Description |
|---|---|---|
configs | no | Matching forwarding configs. |
total | no | Total number of matching configs. |
{"signatures":{"go":"func (x *AdminClient) ListTelemetryConfigs(ctx context.Context, req *adminv1.ListTelemetryConfigsRequest) (*adminv1.ListTelemetryConfigsResponse, error)","python":"list_telemetry_configs(req: admin_pb2.ListTelemetryConfigsRequest) -\u003e ListTelemetryConfigsResponse","typescript":"listTelemetryConfigs(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListTelemetryConfigsRequestSchema\u003e): Promise\u003cListTelemetryConfigsResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListTelemetryConfigsRequest{}\n\n\tresp, err := client.Admin().ListTelemetryConfigs(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listtelemetryconfigs\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListTelemetryConfigsRequest()\ntry:\n result = client.admin.list_telemetry_configs(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listTelemetryConfigs(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/telemetry-configs","slug":"list-telemetry-configs"}
Get telemetry config
What it does: Get telemetry config
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Forwarding config ID to fetch. |
Response fields:
| Field | Required | Description |
|---|---|---|
config | no | The requested forwarding config. |
{"signatures":{"go":"func (x *AdminClient) GetTelemetryConfig(ctx context.Context, req *adminv1.GetTelemetryConfigRequest) (*adminv1.GetTelemetryConfigResponse, error)","python":"get_telemetry_config(req: admin_pb2.GetTelemetryConfigRequest) -\u003e GetTelemetryConfigResponse","typescript":"getTelemetryConfig(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetTelemetryConfigRequestSchema\u003e): Promise\u003cGetTelemetryConfigResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetTelemetryConfigRequest{}\n\n\tresp, err := client.Admin().GetTelemetryConfig(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/gettelemetryconfig\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetTelemetryConfigRequest()\ntry:\n result = client.admin.get_telemetry_config(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getTelemetryConfig(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/telemetry-configs/{id}","slug":"get-telemetry-config"}
Update telemetry config
What it does: Update telemetry config
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Forwarding config ID to update. |
sink_url | no | New sink URL; unset leaves it unchanged. |
protocol | no | New OTLP protocol; unset leaves it unchanged. |
auth_type | no | New auth scheme; unset leaves it unchanged. |
auth_value | no | undocumented |
api_key_header | no | New API key header name; unset leaves it unchanged. |
enabled | no | New enabled flag; unset leaves it unchanged. |
status | no | Override the connection status (connected/disconnected/error/testing). |
forward_interval_seconds | no | New audit-log forward interval in seconds; unset leaves it unchanged. |
Response fields:
| Field | Required | Description |
|---|---|---|
config | no | The updated forwarding config. |
{"signatures":{"go":"func (x *AdminClient) UpdateTelemetryConfig(ctx context.Context, req *adminv1.UpdateTelemetryConfigRequest) (*adminv1.UpdateTelemetryConfigResponse, error)","python":"update_telemetry_config(req: admin_pb2.UpdateTelemetryConfigRequest) -\u003e UpdateTelemetryConfigResponse","typescript":"updateTelemetryConfig(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpdateTelemetryConfigRequestSchema\u003e): Promise\u003cUpdateTelemetryConfigResponse\u003e","curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"sink_url\": \"...\",\n \"protocol\": \"...\",\n \"auth_type\": \"...\",\n \"auth_value\": \"...\",\n \"api_key_header\": \"...\",\n \"enabled\": false,\n \"status\": \"...\",\n \"forward_interval_seconds\": 0\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpdateTelemetryConfigRequest{}\n\n\tresp, err := client.Admin().UpdateTelemetryConfig(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/updatetelemetryconfig\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpdateTelemetryConfigRequest()\ntry:\n result = client.admin.update_telemetry_config(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.updateTelemetryConfig(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"sink_url\": \"...\",\n \"protocol\": \"...\",\n \"auth_type\": \"...\",\n \"auth_value\": \"...\",\n \"api_key_header\": \"...\",\n \"enabled\": false,\n \"status\": \"...\",\n \"forward_interval_seconds\": 0\n }'"},"persona":"Admin","httpVerb":"PATCH","httpPath":"/admin/v1/telemetry-configs/{id}","slug":"update-telemetry-config"}
Delete telemetry config
What it does: Delete telemetry config
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | Forwarding config ID to delete. |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the config was deleted. |
{"signatures":{"go":"func (x *AdminClient) DeleteTelemetryConfig(ctx context.Context, req *adminv1.DeleteTelemetryConfigRequest) (*adminv1.DeleteTelemetryConfigResponse, error)","python":"delete_telemetry_config(req: admin_pb2.DeleteTelemetryConfigRequest) -\u003e DeleteTelemetryConfigResponse","typescript":"deleteTelemetryConfig(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.DeleteTelemetryConfigRequestSchema\u003e): Promise\u003cDeleteTelemetryConfigResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.DeleteTelemetryConfigRequest{}\n\n\tresp, err := client.Admin().DeleteTelemetryConfig(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/deletetelemetryconfig\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.DeleteTelemetryConfigRequest()\ntry:\n result = client.admin.delete_telemetry_config(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.deleteTelemetryConfig(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/admin/v1/telemetry-configs/{id}","slug":"delete-telemetry-config"}
Trigger audit forward
What it does: Trigger an immediate audit-log forward run (real-time push). The management plane kicks the in-process forwarder; the cron ticker is the backstop.
Request fields:
| Field | Required | Description |
|---|---|---|
owner | no | Optional owner hint for logging; the forwarder drains all due configs. |
{"signatures":{"go":"func (x *AdminClient) TriggerAuditForward(ctx context.Context, req *adminv1.TriggerAuditForwardRequest) (*adminv1.TriggerAuditForwardResponse, error)","python":"trigger_audit_forward(req: admin_pb2.TriggerAuditForwardRequest) -\u003e TriggerAuditForwardResponse","typescript":"triggerAuditForward(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.TriggerAuditForwardRequestSchema\u003e): Promise\u003cTriggerAuditForwardResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs/trigger-forward\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"owner\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.TriggerAuditForwardRequest{}\n\n\tresp, err := client.Admin().TriggerAuditForward(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/triggerauditforward\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.TriggerAuditForwardRequest()\ntry:\n result = client.admin.trigger_audit_forward(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.triggerAuditForward(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs/trigger-forward\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"owner\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/telemetry-configs/trigger-forward","slug":"trigger-audit-forward"}
Test audit forward
What it does: Test an audit-log SIEM sink by sending a synthetic OTLP-Logs record via the same path the forwarder uses (POST /v1/logs with the resolved auth). Proves the actual log endpoint + auth, unlike the trace-based bellhop tester.
Request fields:
| Field | Required | Description |
|---|---|---|
sink_url | no | Sink to test (OTLP/HTTP-JSON; the /v1/logs path is appended if absent). |
protocol | no | Wire protocol; only "http/json" is supported for audit-log forwarding. |
auth_type | no | Auth triple. auth_value may be a plaintext credential or a valet://sm:// reference (resolved server-side), mirroring the forwarder. |
auth_value | no | undocumented |
api_key_header | no | undocumented |
owner | no | Optional owner hint for logging. |
Response fields:
| Field | Required | Description |
|---|---|---|
ok | no | True if the synthetic record was accepted (2xx) by the sink. |
message | no | Error/diagnostic detail when ok is false. |
{"signatures":{"go":"func (x *AdminClient) TestAuditForward(ctx context.Context, req *adminv1.TestAuditForwardRequest) (*adminv1.TestAuditForwardResponse, error)","python":"test_audit_forward(req: admin_pb2.TestAuditForwardRequest) -\u003e TestAuditForwardResponse","typescript":"testAuditForward(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.TestAuditForwardRequestSchema\u003e): Promise\u003cTestAuditForwardResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs/test-forward\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"sink_url\": \"...\",\n \"protocol\": \"...\",\n \"auth_type\": \"...\",\n \"auth_value\": \"...\",\n \"api_key_header\": \"...\",\n \"owner\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.TestAuditForwardRequest{}\n\n\tresp, err := client.Admin().TestAuditForward(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/testauditforward\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.TestAuditForwardRequest()\ntry:\n result = client.admin.test_audit_forward(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.testAuditForward(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/telemetry-configs/test-forward\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"sink_url\": \"...\",\n \"protocol\": \"...\",\n \"auth_type\": \"...\",\n \"auth_value\": \"...\",\n \"api_key_header\": \"...\",\n \"owner\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/telemetry-configs/test-forward","slug":"test-audit-forward"}
List audit checkpoints
What it does: List signed Merkle checkpoints (fraser#4599) for chain verification: each checkpoint's prev_root chains to the previous and its signature covers the root. Ordered by seq ascending, starting strictly after after_seq.
Request fields:
| Field | Required | Description |
|---|---|---|
after_seq | no | Return checkpoints with seq strictly greater than this (0 = from the start). |
limit | no | Max checkpoints to return; the server applies a default and a hard cap. |
rebuild | no | When true, the server rebuilds each window from current content and fills content_root_hash/content_leaf_count, so the caller can detect content tampering (edits/deletes/back-dated inserts), not just header/signature tampering. More expensive — it reads every sealed row. |
Response fields:
| Field | Required | Description |
|---|---|---|
checkpoints | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) ListAuditCheckpoints(ctx context.Context, req *adminv1.ListAuditCheckpointsRequest) (*adminv1.ListAuditCheckpointsResponse, error)","python":"list_audit_checkpoints(req: admin_pb2.ListAuditCheckpointsRequest) -\u003e ListAuditCheckpointsResponse","typescript":"listAuditCheckpoints(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListAuditCheckpointsRequestSchema\u003e): Promise\u003cListAuditCheckpointsResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/audit/checkpoints:list\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"after_seq\": 0,\n \"limit\": 0,\n \"rebuild\": false\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListAuditCheckpointsRequest{}\n\n\tresp, err := client.Admin().ListAuditCheckpoints(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listauditcheckpoints\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListAuditCheckpointsRequest()\ntry:\n result = client.admin.list_audit_checkpoints(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listAuditCheckpoints(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/audit/checkpoints:list\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"after_seq\": 0,\n \"limit\": 0,\n \"rebuild\": false\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/audit/checkpoints:list","slug":"list-audit-checkpoints"}
Get audit inclusion proof
What it does: Return the Merkle inclusion proof for an audit_logs row: its leaf hash and audit path recomputed from current content, plus the signed checkpoint it belongs to, so a verifier can confirm the row is committed to a signed root.
Request fields:
| Field | Required | Description |
|---|---|---|
audit_log_id | no | undocumented |
Response fields:
| Field | Required | Description |
|---|---|---|
found | no | found is false when the row is not committed to any checkpoint. |
reason | no | reason explains a false found: "unsealed" (written after the last checkpoint or before the first) or "row_missing" (no such row — a possible deletion). |
leaf_hash | no | leaf_hash is the row's RFC 6962 leaf hash, recomputed from current content. |
proof | no | proof is the Merkle audit path, in leaf-to-root order. |
leaf_index | no | undocumented |
tree_size | no | tree_size is the number of rows currently in the sealed window; a mismatch with checkpoint.leaf_count means rows were inserted or deleted after sealing. |
checkpoint | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) GetAuditInclusionProof(ctx context.Context, req *adminv1.GetAuditInclusionProofRequest) (*adminv1.GetAuditInclusionProofResponse, error)","python":"get_audit_inclusion_proof(req: admin_pb2.GetAuditInclusionProofRequest) -\u003e GetAuditInclusionProofResponse","typescript":"getAuditInclusionProof(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetAuditInclusionProofRequestSchema\u003e): Promise\u003cGetAuditInclusionProofResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/audit/inclusion-proof\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"audit_log_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetAuditInclusionProofRequest{}\n\n\tresp, err := client.Admin().GetAuditInclusionProof(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getauditinclusionproof\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetAuditInclusionProofRequest()\ntry:\n result = client.admin.get_audit_inclusion_proof(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getAuditInclusionProof(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/audit/inclusion-proof\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"audit_log_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/audit/inclusion-proof","slug":"get-audit-inclusion-proof"}
Query audit logs
Changed in v0.10.0 (behaviour changes): Fleet audit reads require explicit platform permissions; organization admin and audit reader scopes no longer grant fleet access. An organization admin who called these methods before keeps working, but sees only their own organization's records, and only records written from 0.10 on, because earlier records have no organization owner.
Changed in v0.10.0 (security updates): Organization-scoped audit reads show records with trusted ownership stamps; fleet-wide reads require an explicit platform audit grant.
Changed in v0.10.0 (security updates): Provisioned admin-scoped secrets also gain QueryAuditLogs and GetAuditLog, with the same fleet visibility already available through QueryPlatformAuditLogs.
Changed in v0.10.0 (deprecations): Calling the fleet audit methods as an organization admin, without a platform audit grant, is deprecated and will be refused in a later release. In 0.10 these calls return only the caller's own organization's records, and only records written from 0.10 on, because records written before the upgrade have no organization owner. The management plane logs a deprecation warning on each such call. Use QueryCustomerAuditLogs and GetCustomerAuditLog for organization reads.
Changed in v0.9.0 (behaviour changes): Audit records for changes made through the Developer Console now name the signed-in user and their email instead of the console's service key. The key ID moves to metadata.via_key. Admin Console calls that already send X-Acting-Session-Token change the same way: user_id changes from the key to the person, and metadata.via_key is added. Audit records of a user or management-key caller now also carry the caller's email.
Changed in v0.9.0 (behaviour changes): An audit record is now written in the same transaction as the change it records. A change that fails or is refused leaves one record with success set to false. Changes made through the workspace API are now audited too.
Changed in v0.9.0 (behaviour changes): The Developer Console no longer writes its own audit records for key rotation, management-key create and delete, and project telemetry changes; the server's ROTATE_CLIENT_KEY, ISSUE_MY_KEY, REVOKE_MY_KEY and CREATE_ or UPDATE_TELEMETRY_CONFIG records cover them. A legacy key rotation (no client) keeps the console record until a later release. A data plane upgrade outcome is now one FINISH_DATAPLANE_UPGRADE record with the final phase in metadata.phase; only Completed has success set to true.
Changed in v0.9.0 (behaviour changes): Until a later release removes the Admin Console's own audit records, an Admin Console change that the server audits leaves two records, and both now name the signed-in user: the console's and the server's. For example, a data plane update writes UPDATE from the console, and UPDATE_DATAPLANE with metadata.via_key from the server.
Changed in v0.9.0 (behaviour changes): Audit records of Developer Console calls now carry the browser's user_agent, and the X-Forwarded-For chain that the console received in metadata.forwarded_for. source_ip stays the address of the console.
Changed in v0.9.0 (new features): Audit log queries accept search, a case-insensitive match over the actor's email, user ID and type, the action, the resource type and ID, the correlation ID, the endpoint, the source IP and the error message. They also accept order_by, which sorts by actor, action, resource, source or outcome. A search that sets no start_time covers the 30 days before the end time (or now), from the start of that UTC day.
Changed in v0.9.0 (bug fixes): The Audit Logs page now loads quickly on a management plane with millions of audit records. It used to read the whole audit table on every load and could time out with "Couldn't load this page".
Changed in v0.5.0 (behaviour changes): Reaching a fleet-wide operation now requires an explicit platform binding for a caller that does not hold the admin scope. A management API key that reached one of these operations on a coarse scope alone, such as read or metrics_reader, is refused after this upgrade.
Changed in v0.5.0 (behaviour changes): Audit entries from the management plane's services now record the call that produced them -- source_ip, user_agent, http_method and endpoint -- and name the user an action was performed on under the subject_user_id metadata key. Key lifecycle entries use one vocabulary: ISSUE_MY_KEY, REVOKE_MY_KEY, ROTATE_CLIENT_KEY, UPDATE_API_KEY and DELETE_API_KEY, with resource_type api_key and actor_type USER or SERVICE.
Changed in v0.5.0 (new features): QueryAuditLogs and QueryPlatformAuditLogs accept subject_user_id, which selects the entries where a user was acted upon rather than the entries they performed themselves. An admin minting a key for a service identity is now findable from either side: user_id names the admin, subject_user_id names the identity.
Changed in v0.5.0 (bug fixes): Scoped management API keys can now reach audit-log and metrics operations without organization or project fields. The handler applies the relevant workspace, organization or platform boundary for each operation.
Changed in v0.2.0 (new features): The audit log query RPCs (QueryAuditLogs and QueryPlatformAuditLogs) can now return success and failure counts alongside the page of entries. Set include_stats and read the new stats field instead of running an extra query per count. The counts obey every filter except success, so a view filtered to one outcome still shows both numbers. The response is unchanged when include_stats is not set.
What it does: Query stored audit_logs entries with filtering and pagination. The read complement to the SIEM forwarder (which only exports) and the checkpoint verification RPCs (which only prove tamper-evidence): list and inspect entries over the API instead of standing up a SIEM.
Request fields:
| Field | Required | Description |
|---|---|---|
user_id | no | Filter by the user id that performed the action. |
actor_type | no | Filter by actor type (e.g. "user", "system", "service_account"). |
action_type | no | Filter by action type (e.g. "CREATE", "UPDATE", "DELETE", "UPGRADE"). |
resource_type | no | Filter by resource type (e.g. "provider", "api_key", "dataplane"). |
resource_id | no | Filter by the affected resource id. |
success | no | Filter by outcome; unset matches both successes and failures. |
correlation_id | no | Filter by correlation id (groups related entries from one operation). |
start_time | no | Start of the time range, inclusive. |
end_time | no | End of the time range, exclusive. |
page_size | no | Max entries per page; the server applies a default (50) and a hard cap (1000). |
page_token | no | Opaque token from a prior response's next_page_token. |
order_direction | no | Sort direction: "asc" or "desc" (default "desc", newest first). Applies to order_by, which defaults to the timestamp. |
include_stats | no | When true the response carries stats, the success/failure split computed in the same database round trip as total_count. Lets a summary UI render total/success/failure from one call instead of one page_size=1 query per aggregate. |
subject_user_id | no | Filter by the user the action was performed ON, which is not always the user who performed it: an admin minting a key for a service identity puts the admin in user_id and the identity here. Ask "what was done to this user" with this field and "what did this user do" with user_id. |
search | no | Free-text search: a case-insensitive substring match over user_email, user_id, actor_type, action_type, resource_type, resource_id, correlation_id, endpoint, source_ip and error_message. %, _ and \ match as literal characters. total_count and stats apply it too. Empty or whitespace-only means no search. A search with no start_time reads only from the start of the UTC day 30 days before the end time (end_time, or now when end_time is unset); set start_time to search further back. |
order_by | no | Sort key: "timestamp", "actor" (user_email, user_id), "action", "resource" (resource_type, resource_id), "source" (source_ip) or "outcome" (success). Empty means "timestamp". order_direction applies to the key; a key other than timestamp puts empty values last and breaks ties by timestamp and id, newest first, so pages stay stable. A sort alone does not narrow the time window; only a search does. |
Response fields:
| Field | Required | Description |
|---|---|---|
logs | no | undocumented |
next_page_token | no | Token to pass back as page_token for the next page; empty when exhausted. |
total_count | no | Total number of matching entries across all pages. Unlike stats, this honours the success filter -- it is the count this page is paging through. |
stats | no | Outcome split; present only when the request set include_stats. |
{"signatures":{"go":"func (x *AdminClient) QueryAuditLogs(ctx context.Context, req *adminv1.QueryAuditLogsRequest) (*adminv1.QueryAuditLogsResponse, error)","python":"query_audit_logs(req: admin_pb2.QueryAuditLogsRequest) -\u003e QueryAuditLogsResponse","typescript":"queryAuditLogs(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.QueryAuditLogsRequestSchema\u003e): Promise\u003cQueryAuditLogsResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/audit/logs:query\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"user_id\": \"...\",\n \"actor_type\": \"...\",\n \"action_type\": \"...\",\n \"resource_type\": \"...\",\n \"resource_id\": \"...\",\n \"success\": false,\n \"correlation_id\": \"...\",\n \"start_time\": {},\n \"end_time\": {},\n \"page_size\": 0,\n \"page_token\": \"...\",\n \"order_direction\": \"...\",\n \"include_stats\": false,\n \"subject_user_id\": \"...\",\n \"search\": \"...\",\n \"order_by\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.QueryAuditLogsRequest{}\n\n\tresp, err := client.Admin().QueryAuditLogs(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/queryauditlogs\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.QueryAuditLogsRequest()\ntry:\n result = client.admin.query_audit_logs(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.queryAuditLogs(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/audit/logs:query\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"user_id\": \"...\",\n \"actor_type\": \"...\",\n \"action_type\": \"...\",\n \"resource_type\": \"...\",\n \"resource_id\": \"...\",\n \"success\": false,\n \"correlation_id\": \"...\",\n \"start_time\": {},\n \"end_time\": {},\n \"page_size\": 0,\n \"page_token\": \"...\",\n \"order_direction\": \"...\",\n \"include_stats\": false,\n \"subject_user_id\": \"...\",\n \"search\": \"...\",\n \"order_by\": \"...\"\n }'"},"persona":"App Developer (API key)","httpVerb":"POST","httpPath":"/admin/v1/audit/logs:query","slug":"query-audit-logs"}
Get audit log
Changed in v0.10.0 (behaviour changes): Fleet audit reads require explicit platform permissions; organization admin and audit reader scopes no longer grant fleet access. An organization admin who called these methods before keeps working, but sees only their own organization's records, and only records written from 0.10 on, because earlier records have no organization owner.
Changed in v0.10.0 (security updates): Organization-scoped audit reads show records with trusted ownership stamps; fleet-wide reads require an explicit platform audit grant.
Changed in v0.10.0 (security updates): Provisioned admin-scoped secrets also gain QueryAuditLogs and GetAuditLog, with the same fleet visibility already available through QueryPlatformAuditLogs.
Changed in v0.10.0 (deprecations): Calling the fleet audit methods as an organization admin, without a platform audit grant, is deprecated and will be refused in a later release. In 0.10 these calls return only the caller's own organization's records, and only records written from 0.10 on, because records written before the upgrade have no organization owner. The management plane logs a deprecation warning on each such call. Use QueryCustomerAuditLogs and GetCustomerAuditLog for organization reads.
Changed in v0.5.0 (behaviour changes): Reaching a fleet-wide operation now requires an explicit platform binding for a caller that does not hold the admin scope. A management API key that reached one of these operations on a coarse scope alone, such as read or metrics_reader, is refused after this upgrade.
Changed in v0.5.0 (bug fixes): Scoped management API keys can now reach audit-log and metrics operations without organization or project fields. The handler applies the relevant workspace, organization or platform boundary for each operation.
What it does: Get a single audit_logs entry by id.
Request fields:
| Field | Required | Description |
|---|---|---|
id | no | UUID of the audit log entry to fetch. |
Response fields:
| Field | Required | Description |
|---|---|---|
id | no | Server-generated audit entry UUID (primary key). |
timestamp | no | When the audited action occurred. |
user_id | no | Id of the user that performed the action; empty for system actions. |
user_email | no | Email of the acting user, captured at write time. |
actor_type | no | Actor category (e.g. "user", "system", "service_account"). |
action_type | no | Action performed (e.g. "CREATE", "UPDATE", "DELETE", "UPGRADE"). |
resource_type | no | Type of the affected resource (e.g. "provider", "api_key", "dataplane"). |
resource_id | no | Id of the affected resource. |
source_ip | no | Client IP the request originated from. |
user_agent | no | User-Agent header of the originating request. |
http_method | no | HTTP method of the originating request (e.g. "POST"). |
endpoint | no | Request path / RPC endpoint that triggered the action. |
status_code | no | HTTP status code of the response. |
success | no | Whether the action succeeded. |
request_params | no | Request path/query parameters captured for the action. |
request_body | no | Request body captured for the action (sensitive values may be redacted). |
response_data | no | Response payload captured for the action. |
error_message | no | Error detail when the action failed; empty on success. |
correlation_id | no | Correlation id grouping related entries from one operation. |
metadata | no | Additional structured context attached to the entry. |
created_at | no | When the audit row was persisted (defaults to the event time). |
{"signatures":{"go":"func (x *AdminClient) GetAuditLog(ctx context.Context, req *adminv1.GetAuditLogRequest) (*adminv1.AuditLogEntry, error)","python":"get_audit_log(req: admin_pb2.GetAuditLogRequest) -\u003e AuditLogEntry","typescript":"getAuditLog(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetAuditLogRequestSchema\u003e): Promise\u003cAuditLogEntry\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/audit/logs/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetAuditLogRequest{}\n\n\tresp, err := client.Admin().GetAuditLog(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getauditlog\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetAuditLogRequest()\ntry:\n result = client.admin.get_audit_log(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getAuditLog(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/audit/logs/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"App Developer (API key)","httpVerb":"GET","httpPath":"/admin/v1/audit/logs/{id}","slug":"get-audit-log"}
Query platform audit logs
Changed in v0.11.0 (bug fixes): A request with a NUL character in a name, description or filter field now returns 400 invalid_argument. It returned 500 internal before, which clients retry and which counted as a server failure. This applies when the management plane uses the extended query protocol, which is the default. A deployment that sets global.useSimpleProtocol (USE_QUERY_EXEC_MODE_SIMPLE_PROTOCOL=true, used with pgbouncer) still returns 500 for these requests.
Changed in v0.10.0 (behaviour changes): Fleet audit reads require explicit platform permissions; organization admin and audit reader scopes no longer grant fleet access. An organization admin who called these methods before keeps working, but sees only their own organization's records, and only records written from 0.10 on, because earlier records have no organization owner.
Changed in v0.10.0 (security updates): Organization-scoped audit reads show records with trusted ownership stamps; fleet-wide reads require an explicit platform audit grant.
Changed in v0.10.0 (deprecations): Calling the fleet audit methods as an organization admin, without a platform audit grant, is deprecated and will be refused in a later release. In 0.10 these calls return only the caller's own organization's records, and only records written from 0.10 on, because records written before the upgrade have no organization owner. The management plane logs a deprecation warning on each such call. Use QueryCustomerAuditLogs and GetCustomerAuditLog for organization reads.
Changed in v0.9.0 (behaviour changes): Audit records for changes made through the Developer Console now name the signed-in user and their email instead of the console's service key. The key ID moves to metadata.via_key. Admin Console calls that already send X-Acting-Session-Token change the same way: user_id changes from the key to the person, and metadata.via_key is added. Audit records of a user or management-key caller now also carry the caller's email.
Changed in v0.9.0 (behaviour changes): An audit record is now written in the same transaction as the change it records. A change that fails or is refused leaves one record with success set to false. Changes made through the workspace API are now audited too.
Changed in v0.9.0 (behaviour changes): The Developer Console no longer writes its own audit records for key rotation, management-key create and delete, and project telemetry changes; the server's ROTATE_CLIENT_KEY, ISSUE_MY_KEY, REVOKE_MY_KEY and CREATE_ or UPDATE_TELEMETRY_CONFIG records cover them. A legacy key rotation (no client) keeps the console record until a later release. A data plane upgrade outcome is now one FINISH_DATAPLANE_UPGRADE record with the final phase in metadata.phase; only Completed has success set to true.
Changed in v0.9.0 (behaviour changes): Until a later release removes the Admin Console's own audit records, an Admin Console change that the server audits leaves two records, and both now name the signed-in user: the console's and the server's. For example, a data plane update writes UPDATE from the console, and UPDATE_DATAPLANE with metadata.via_key from the server.
Changed in v0.9.0 (behaviour changes): Audit records of Developer Console calls now carry the browser's user_agent, and the X-Forwarded-For chain that the console received in metadata.forwarded_for. source_ip stays the address of the console.
Changed in v0.9.0 (new features): Audit log queries accept search, a case-insensitive match over the actor's email, user ID and type, the action, the resource type and ID, the correlation ID, the endpoint, the source IP and the error message. They also accept order_by, which sorts by actor, action, resource, source or outcome. A search that sets no start_time covers the 30 days before the end time (or now), from the start of that UTC day.
Changed in v0.9.0 (bug fixes): The Audit Logs page now loads quickly on a management plane with millions of audit records. It used to read the whole audit table on every load and could time out with "Couldn't load this page".
Changed in v0.5.0 (behaviour changes): Audit entries from the management plane's services now record the call that produced them -- source_ip, user_agent, http_method and endpoint -- and name the user an action was performed on under the subject_user_id metadata key. Key lifecycle entries use one vocabulary: ISSUE_MY_KEY, REVOKE_MY_KEY, ROTATE_CLIENT_KEY, UPDATE_API_KEY and DELETE_API_KEY, with resource_type api_key and actor_type USER or SERVICE.
Changed in v0.5.0 (new features): QueryAuditLogs and QueryPlatformAuditLogs accept subject_user_id, which selects the entries where a user was acted upon rather than the entries they performed themselves. An admin minting a key for a service identity is now findable from either side: user_id names the admin, subject_user_id names the identity.
Changed in v0.2.0 (new features): The audit log query RPCs (QueryAuditLogs and QueryPlatformAuditLogs) can now return success and failure counts alongside the page of entries. Set include_stats and read the new stats field instead of running an extra query per count. The counts obey every filter except success, so a view filtered to one outcome still shows both numbers. The response is unchanged when include_stats is not set.
What it does: Is the fleet-wide audit query. It requires an explicit platform_audit_logs.read grant, such as platform_admin; organization admin scope alone does not grant fleet access. An organization admin without that grant reads only its own organization's records, which is deprecated; use QueryCustomerAuditLogs. Same request/response as QueryAuditLogs.
Request fields:
| Field | Required | Description |
|---|---|---|
user_id | no | Filter by the user id that performed the action. |
actor_type | no | Filter by actor type (e.g. "user", "system", "service_account"). |
action_type | no | Filter by action type (e.g. "CREATE", "UPDATE", "DELETE", "UPGRADE"). |
resource_type | no | Filter by resource type (e.g. "provider", "api_key", "dataplane"). |
resource_id | no | Filter by the affected resource id. |
success | no | Filter by outcome; unset matches both successes and failures. |
correlation_id | no | Filter by correlation id (groups related entries from one operation). |
start_time | no | Start of the time range, inclusive. |
end_time | no | End of the time range, exclusive. |
page_size | no | Max entries per page; the server applies a default (50) and a hard cap (1000). |
page_token | no | Opaque token from a prior response's next_page_token. |
order_direction | no | Sort direction: "asc" or "desc" (default "desc", newest first). Applies to order_by, which defaults to the timestamp. |
include_stats | no | When true the response carries stats, the success/failure split computed in the same database round trip as total_count. Lets a summary UI render total/success/failure from one call instead of one page_size=1 query per aggregate. |
subject_user_id | no | Filter by the user the action was performed ON, which is not always the user who performed it: an admin minting a key for a service identity puts the admin in user_id and the identity here. Ask "what was done to this user" with this field and "what did this user do" with user_id. |
search | no | Free-text search: a case-insensitive substring match over user_email, user_id, actor_type, action_type, resource_type, resource_id, correlation_id, endpoint, source_ip and error_message. %, _ and \ match as literal characters. total_count and stats apply it too. Empty or whitespace-only means no search. A search with no start_time reads only from the start of the UTC day 30 days before the end time (end_time, or now when end_time is unset); set start_time to search further back. |
order_by | no | Sort key: "timestamp", "actor" (user_email, user_id), "action", "resource" (resource_type, resource_id), "source" (source_ip) or "outcome" (success). Empty means "timestamp". order_direction applies to the key; a key other than timestamp puts empty values last and breaks ties by timestamp and id, newest first, so pages stay stable. A sort alone does not narrow the time window; only a search does. |
Response fields:
| Field | Required | Description |
|---|---|---|
logs | no | undocumented |
next_page_token | no | Token to pass back as page_token for the next page; empty when exhausted. |
total_count | no | Total number of matching entries across all pages. Unlike stats, this honours the success filter -- it is the count this page is paging through. |
stats | no | Outcome split; present only when the request set include_stats. |
{"signatures":{"go":"func (x *AdminClient) QueryPlatformAuditLogs(ctx context.Context, req *adminv1.QueryAuditLogsRequest) (*adminv1.QueryAuditLogsResponse, error)","python":"query_platform_audit_logs(req: admin_pb2.QueryAuditLogsRequest) -\u003e QueryAuditLogsResponse","typescript":"queryPlatformAuditLogs(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.QueryAuditLogsRequestSchema\u003e): Promise\u003cQueryAuditLogsResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/platform/audit/logs:query\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"user_id\": \"...\",\n \"actor_type\": \"...\",\n \"action_type\": \"...\",\n \"resource_type\": \"...\",\n \"resource_id\": \"...\",\n \"success\": false,\n \"correlation_id\": \"...\",\n \"start_time\": {},\n \"end_time\": {},\n \"page_size\": 0,\n \"page_token\": \"...\",\n \"order_direction\": \"...\",\n \"include_stats\": false,\n \"subject_user_id\": \"...\",\n \"search\": \"...\",\n \"order_by\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.QueryAuditLogsRequest{}\n\n\tresp, err := client.Admin().QueryPlatformAuditLogs(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/queryplatformauditlogs\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.QueryAuditLogsRequest()\ntry:\n result = client.admin.query_platform_audit_logs(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.queryPlatformAuditLogs(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/platform/audit/logs:query\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"user_id\": \"...\",\n \"actor_type\": \"...\",\n \"action_type\": \"...\",\n \"resource_type\": \"...\",\n \"resource_id\": \"...\",\n \"success\": false,\n \"correlation_id\": \"...\",\n \"start_time\": {},\n \"end_time\": {},\n \"page_size\": 0,\n \"page_token\": \"...\",\n \"order_direction\": \"...\",\n \"include_stats\": false,\n \"subject_user_id\": \"...\",\n \"search\": \"...\",\n \"order_by\": \"...\"\n }'"},"persona":"App Developer (API key)","httpVerb":"POST","httpPath":"/admin/v1/platform/audit/logs:query","slug":"query-platform-audit-logs"}
Query customer audit logs
Changed in v0.10.0 (security updates): Organization-scoped audit reads show records with trusted ownership stamps; fleet-wide reads require an explicit platform audit grant.
Changed in v0.10.0 (new features): Organization audit log reads now include customer update and archive, project, project member, AI key, model assignment, MCP profile, MCP profile act-as, MCP OAuth client, API key, budget alert, data plane and project gateway changes, and on a single-organization deployment user role and SSO provider changes. Refused requests and fleet-wide actions stay out, and so do records written before the upgrade. That is because no earlier release writes an organization owner on an audit record.
What it does: Query audit entries owned by one customer. This read is confined to the caller's API-key customer/project boundary; it does not provide fleet visibility. Rows without a trusted ownership stamp remain platform-only.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | yes | Required tenant owner. Must match the customer bound to the API key. |
project_id | no | Optional project narrowing. Project-bound keys must name their bound project; organization keys may omit it to read the customer-wide set. |
filters | no | Audit query filters, ordering and pagination. The tenant predicates are applied separately by the server and cannot be overridden here. |
Response fields:
| Field | Required | Description |
|---|---|---|
logs | no | undocumented |
next_page_token | no | Token to pass back as page_token for the next page; empty when exhausted. |
total_count | no | Total number of matching entries across all pages. Unlike stats, this honours the success filter -- it is the count this page is paging through. |
stats | no | Outcome split; present only when the request set include_stats. |
{"signatures":{"go":"func (x *AdminClient) QueryCustomerAuditLogs(ctx context.Context, req *adminv1.QueryCustomerAuditLogsRequest) (*adminv1.QueryAuditLogsResponse, error)","python":"query_customer_audit_logs(req: admin_pb2.QueryCustomerAuditLogsRequest) -\u003e QueryAuditLogsResponse","typescript":"queryCustomerAuditLogs(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.QueryCustomerAuditLogsRequestSchema\u003e): Promise\u003cQueryAuditLogsResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../audit/logs:query\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\",\n \"filters\": {}\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.QueryCustomerAuditLogsRequest{}\n\n\tresp, err := client.Admin().QueryCustomerAuditLogs(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/querycustomerauditlogs\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.QueryCustomerAuditLogsRequest()\ntry:\n result = client.admin.query_customer_audit_logs(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.queryCustomerAuditLogs(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../audit/logs:query\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\",\n \"filters\": {}\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/audit/logs:query","slug":"query-customer-audit-logs"}
Get customer audit log
Changed in v0.10.0 (security updates): Organization-scoped audit reads show records with trusted ownership stamps; fleet-wide reads require an explicit platform audit grant.
Changed in v0.10.0 (new features): Organization audit log reads now include customer update and archive, project, project member, AI key, model assignment, MCP profile, MCP profile act-as, MCP OAuth client, API key, budget alert, data plane and project gateway changes, and on a single-organization deployment user role and SSO provider changes. Refused requests and fleet-wide actions stay out, and so do records written before the upgrade. That is because no earlier release writes an organization owner on an audit record.
What it does: Get one audit entry only when its trusted ownership matches the supplied customer and optional project boundary. A foreign UUID is returned as NotFound, the same as an unknown UUID.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | yes | Required tenant owner. Must match the customer bound to the API key. |
project_id | no | Optional project narrowing. Required for a project-bound API key. |
id | no | UUID of the entry to fetch. |
Response fields:
| Field | Required | Description |
|---|---|---|
id | no | Server-generated audit entry UUID (primary key). |
timestamp | no | When the audited action occurred. |
user_id | no | Id of the user that performed the action; empty for system actions. |
user_email | no | Email of the acting user, captured at write time. |
actor_type | no | Actor category (e.g. "user", "system", "service_account"). |
action_type | no | Action performed (e.g. "CREATE", "UPDATE", "DELETE", "UPGRADE"). |
resource_type | no | Type of the affected resource (e.g. "provider", "api_key", "dataplane"). |
resource_id | no | Id of the affected resource. |
source_ip | no | Client IP the request originated from. |
user_agent | no | User-Agent header of the originating request. |
http_method | no | HTTP method of the originating request (e.g. "POST"). |
endpoint | no | Request path / RPC endpoint that triggered the action. |
status_code | no | HTTP status code of the response. |
success | no | Whether the action succeeded. |
request_params | no | Request path/query parameters captured for the action. |
request_body | no | Request body captured for the action (sensitive values may be redacted). |
response_data | no | Response payload captured for the action. |
error_message | no | Error detail when the action failed; empty on success. |
correlation_id | no | Correlation id grouping related entries from one operation. |
metadata | no | Additional structured context attached to the entry. |
created_at | no | When the audit row was persisted (defaults to the event time). |
{"signatures":{"go":"func (x *AdminClient) GetCustomerAuditLog(ctx context.Context, req *adminv1.GetCustomerAuditLogRequest) (*adminv1.AuditLogEntry, error)","python":"get_customer_audit_log(req: admin_pb2.GetCustomerAuditLogRequest) -\u003e AuditLogEntry","typescript":"getCustomerAuditLog(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetCustomerAuditLogRequestSchema\u003e): Promise\u003cAuditLogEntry\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../audit/logs/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetCustomerAuditLogRequest{}\n\n\tresp, err := client.Admin().GetCustomerAuditLog(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getcustomerauditlog\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetCustomerAuditLogRequest()\ntry:\n result = client.admin.get_customer_audit_log(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getCustomerAuditLog(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../audit/logs/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/audit/logs/{id}","slug":"get-customer-audit-log"}
Create customer
Changed in v0.1.5 (bug fixes): Creating an organization now rejects an organization ID that does not match the documented slug format (lowercase letters, digits, and internal hyphens, 63 characters maximum). The API previously accepted any non-empty string. Existing organizations are not affected; the check applies only when an organization is created.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Caller-chosen customer slug, unique across the deployment. |
name | no | Optional display name. |
description | no | Optional description. |
labels | no | Optional user-defined labels. |
Response fields:
| Field | Required | Description |
|---|---|---|
customer | no | The newly created customer. |
{"signatures":{"go":"func (x *AdminClient) CreateCustomer(ctx context.Context, req *adminv1.CreateCustomerRequest) (*adminv1.CreateCustomerResponse, error)","python":"create_customer(req: admin_pb2.CreateCustomerRequest) -\u003e CreateCustomerResponse","typescript":"createCustomer(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.CreateCustomerRequestSchema\u003e): Promise\u003cCreateCustomerResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {}\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.CreateCustomerRequest{}\n\n\tresp, err := client.Admin().CreateCustomer(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/createcustomer\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.CreateCustomerRequest()\ntry:\n result = client.admin.create_customer(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.createCustomer(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"customer_id\": \"...\",\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {}\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers","slug":"create-customer"}
List customers
Request fields:
| Field | Required | Description |
|---|---|---|
page_size | no | Max results per page (0 = server default). |
page_token | no | Opaque pagination cursor from a prior response. |
Response fields:
| Field | Required | Description |
|---|---|---|
customers | no | Page of customers. |
next_page_token | no | Cursor for the next page; empty when exhausted. |
{"signatures":{"go":"func (x *AdminClient) ListCustomers(ctx context.Context, req *adminv1.ListCustomersRequest) (*adminv1.ListCustomersResponse, error)","python":"list_customers(req: admin_pb2.ListCustomersRequest) -\u003e ListCustomersResponse","typescript":"listCustomers(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListCustomersRequestSchema\u003e): Promise\u003cListCustomersResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListCustomersRequest{}\n\n\tresp, err := client.Admin().ListCustomers(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listcustomers\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListCustomersRequest()\ntry:\n result = client.admin.list_customers(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listCustomers(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers","slug":"list-customers"}
Get customer
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Customer slug to fetch. |
Response fields:
| Field | Required | Description |
|---|---|---|
customer | no | The requested customer. |
{"signatures":{"go":"func (x *AdminClient) GetCustomer(ctx context.Context, req *adminv1.GetCustomerRequest) (*adminv1.GetCustomerResponse, error)","python":"get_customer(req: admin_pb2.GetCustomerRequest) -\u003e GetCustomerResponse","typescript":"getCustomer(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetCustomerRequestSchema\u003e): Promise\u003cGetCustomerResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetCustomerRequest{}\n\n\tresp, err := client.Admin().GetCustomer(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getcustomer\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetCustomerRequest()\ntry:\n result = client.admin.get_customer(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getCustomer(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}","slug":"get-customer"}
Update customer
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Customer slug to update. |
name | no | New display name; unset leaves it unchanged. |
description | no | New description; unset leaves it unchanged. |
labels | no | Replacement set of labels. |
Response fields:
| Field | Required | Description |
|---|---|---|
customer | no | The updated customer. |
{"signatures":{"go":"func (x *AdminClient) UpdateCustomer(ctx context.Context, req *adminv1.UpdateCustomerRequest) (*adminv1.UpdateCustomerResponse, error)","python":"update_customer(req: admin_pb2.UpdateCustomerRequest) -\u003e UpdateCustomerResponse","typescript":"updateCustomer(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpdateCustomerRequestSchema\u003e): Promise\u003cUpdateCustomerResponse\u003e","curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {}\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpdateCustomerRequest{}\n\n\tresp, err := client.Admin().UpdateCustomer(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/updatecustomer\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpdateCustomerRequest()\ntry:\n result = client.admin.update_customer(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.updateCustomer(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {}\n }'"},"persona":"Admin","httpVerb":"PATCH","httpPath":"/admin/v1/customers/{customer_id}","slug":"update-customer"}
Delete customer
soft-delete rename; returns Empty, so the old success/deleted_at response fields go away
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Customer slug to soft-delete. |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the customer was deleted. |
deleted_at | no | When the soft delete took effect. |
{"signatures":{"go":"func (x *AdminClient) DeleteCustomer(ctx context.Context, req *adminv1.DeleteCustomerRequest) (*adminv1.DeleteCustomerResponse, error)","python":"delete_customer(req: admin_pb2.DeleteCustomerRequest) -\u003e DeleteCustomerResponse","typescript":"deleteCustomer(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.DeleteCustomerRequestSchema\u003e): Promise\u003cDeleteCustomerResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.DeleteCustomerRequest{}\n\n\tresp, err := client.Admin().DeleteCustomer(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/deletecustomer\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.DeleteCustomerRequest()\ntry:\n result = client.admin.delete_customer(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.deleteCustomer(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/admin/v1/customers/{customer_id}","slug":"delete-customer"}
Create project
Changed in v0.1.5 (bug fixes): A project created through the admin API now starts with its caller as an administrator, so it can be managed and have keys minted right away. Previously a project created this way could come out with no members: its management page read "unavailable" and nobody could administer it or mint keys for its users. A caller with no resolvable user identity (a legacy admin API key) still creates an unowned project, now recorded so it can be found and repaired.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Customer slug that will own the project. |
project_id | no | Caller-chosen project slug, unique within the customer. |
name | no | Optional display name. |
description | no | Optional description. |
labels | no | Optional user-defined labels. |
Response fields:
| Field | Required | Description |
|---|---|---|
project | no | The newly created project. |
{"signatures":{"go":"func (x *AdminClient) CreateProject(ctx context.Context, req *adminv1.CreateProjectRequest) (*adminv1.CreateProjectResponse, error)","python":"create_project(req: admin_pb2.CreateProjectRequest) -\u003e CreateProjectResponse","typescript":"createProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.CreateProjectRequestSchema\u003e): Promise\u003cCreateProjectResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\",\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {}\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.CreateProjectRequest{}\n\n\tresp, err := client.Admin().CreateProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/createproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.CreateProjectRequest()\ntry:\n result = client.admin.create_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.createProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"project_id\": \"...\",\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {}\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/projects","slug":"create-project"}
List projects
Changed in v0.9.0 (new features): Projects now carry preferred_endpoint_url, the address a project owner starred, as tenancy.v1 projects do.
Changed in v0.1.5 (bug fixes): Listing projects now paginates. The project list endpoints accepted a page token and ignored it, always reporting that no further pages existed, so a organization with more projects than one page silently saw only the first, and a caller had no way to tell a full page from a truncated one. Callers that follow the next-page token now receive every project.
Changed in v0.1.5 (bug fixes): Projects can now be listed in a requested order, by creation time or by project id, so a client no longer has to re-sort every response. An unsupported sort field, or a filter expression the endpoint does not implement, is now rejected with a clear error rather than silently ignored, which previously returned an unsorted or unfiltered list that looked like an answer.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Customer slug whose projects to list. |
page_size | no | Max results per page (0 = server default). |
page_token | no | Opaque pagination cursor from a prior response. |
Response fields:
| Field | Required | Description |
|---|---|---|
projects | no | Page of projects. |
next_page_token | no | Cursor for the next page; empty when exhausted. |
{"signatures":{"go":"func (x *AdminClient) ListProjects(ctx context.Context, req *adminv1.ListProjectsRequest) (*adminv1.ListProjectsResponse, error)","python":"list_projects(req: admin_pb2.ListProjectsRequest) -\u003e ListProjectsResponse","typescript":"listProjects(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectsRequestSchema\u003e): Promise\u003cListProjectsResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectsRequest{}\n\n\tresp, err := client.Admin().ListProjects(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojects\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectsRequest()\ntry:\n result = client.admin.list_projects(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjects(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects","slug":"list-projects"}
Ensure default project
Changed in v0.9.0 (new features): EnsureDefaultProject creates an organization's default project when it does not exist yet, with the enabled providers, MCP servers and models, and returns it. An existing default project is returned as it is, so an allow-list that you emptied stays empty.
Changed in v0.9.0 (new features): Projects now carry preferred_endpoint_url, the address a project owner starred, as tenancy.v1 projects do.
What it does: Creates the customer's reserved default project when it does not exist, seeded with the enabled providers, MCP servers and models, and returns it. An existing default project is returned unchanged, so an allow-list an operator emptied stays empty (fraser#7281). The Admin Console calls it in place of its own seed (fraser#10810). Idempotent and safe to call concurrently.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
Response fields:
| Field | Required | Description |
|---|---|---|
project | no | The customer's default project. |
{"signatures":{"go":"func (x *AdminClient) EnsureDefaultProject(ctx context.Context, req *adminv1.EnsureDefaultProjectRequest) (*adminv1.EnsureDefaultProjectResponse, error)","python":"ensure_default_project(req: admin_pb2.EnsureDefaultProjectRequest) -\u003e EnsureDefaultProjectResponse","typescript":"ensureDefaultProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.EnsureDefaultProjectRequestSchema\u003e): Promise\u003cEnsureDefaultProjectResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/default:ensure\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{}'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.EnsureDefaultProjectRequest{}\n\n\tresp, err := client.Admin().EnsureDefaultProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/ensuredefaultproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.EnsureDefaultProjectRequest()\ntry:\n result = client.admin.ensure_default_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.ensureDefaultProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/default:ensure\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{}'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/projects/default:ensure","slug":"ensure-default-project"}
Get project
Changed in v0.9.0 (new features): Projects now carry preferred_endpoint_url, the address a project owner starred, as tenancy.v1 projects do.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project slug to fetch. |
Response fields:
| Field | Required | Description |
|---|---|---|
project | no | The requested project. |
{"signatures":{"go":"func (x *AdminClient) GetProject(ctx context.Context, req *adminv1.GetProjectRequest) (*adminv1.GetProjectResponse, error)","python":"get_project(req: admin_pb2.GetProjectRequest) -\u003e GetProjectResponse","typescript":"getProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetProjectRequestSchema\u003e): Promise\u003cGetProjectResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetProjectRequest{}\n\n\tresp, err := client.Admin().GetProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetProjectRequest()\ntry:\n result = client.admin.get_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}","slug":"get-project"}
Update project
Changed in v0.11.0 (bug fixes): A request with a NUL character in a name, description or filter field now returns 400 invalid_argument. It returned 500 internal before, which clients retry and which counted as a server failure. This applies when the management plane uses the extended query protocol, which is the default. A deployment that sets global.useSimpleProtocol (USE_QUERY_EXEC_MODE_SIMPLE_PROTOCOL=true, used with pgbouncer) still returns 500 for these requests.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project slug to update. |
name | no | New display name; unset leaves it unchanged. |
description | no | New description; unset leaves it unchanged. |
labels | no | Replacement set of labels. |
public_endpoint_url | no | New project endpoint URL; unset leaves it unchanged, empty string clears it. This is the OPPOSITE of name/description above, which are assigned unconditionally — omitting those clears them, so callers must send the full tuple. The endpoint URL is tri-state precisely because it is edited from a different surface, and a rename must not silently wipe the URL developers are copying out of the console. Format-validated only — see Project.public_endpoint_url. |
Response fields:
| Field | Required | Description |
|---|---|---|
project | no | The updated project. |
{"signatures":{"go":"func (x *AdminClient) UpdateProject(ctx context.Context, req *adminv1.UpdateProjectRequest) (*adminv1.UpdateProjectResponse, error)","python":"update_project(req: admin_pb2.UpdateProjectRequest) -\u003e UpdateProjectResponse","typescript":"updateProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpdateProjectRequestSchema\u003e): Promise\u003cUpdateProjectResponse\u003e","curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {},\n \"public_endpoint_url\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpdateProjectRequest{}\n\n\tresp, err := client.Admin().UpdateProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/updateproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpdateProjectRequest()\ntry:\n result = client.admin.update_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.updateProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"name\": \"...\",\n \"description\": \"...\",\n \"labels\": {},\n \"public_endpoint_url\": \"...\"\n }'"},"persona":"Admin","httpVerb":"PATCH","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}","slug":"update-project"}
Delete project
Changed in v0.11.0 (behaviour changes): Deleting or archiving a project now also hides the API keys that were revoked before it, so a new project with the same name does not list them as its own. ListApiKeys reports these keys as API_KEY_STATUS_DELETED, not API_KEY_STATUS_REVOKED; each keeps its revocation stamp and stays on the data plane's revocation list.
Changed in v0.8.0 (bug fixes): Getting, setting or deleting a project setting now returns NOT_FOUND when the project is missing or deleted. Deleting a project now deletes its settings, so a new project with the same name starts with none. The default project is still created on demand.
Changed in v0.7.0 (behaviour changes): Deleting a project now revokes the API keys scoped to it, rather than refusing while any of them is live. Previously an administrator revoked each key by hand and only then deleted the project. The revoked keys stop being accepted at once, and each data plane drops the routes they carried at its next configuration update.
Changed in v0.7.0 (new features): DeleteProject now answers with the data planes whose label for the project it removed, so a caller confirming a delete reads the affected fleet out of the delete's own response rather than a follow-up call. Each of them serves the configuration it last pulled until its next pull lands, so the list names what is now clearing rather than what has cleared, and GetProjectDeletionImpact reports how far each has got.
Changed in v0.7.0 (bug fixes): Deleting a project that shares a gateway with another project no longer stops that gateway serving the other project, and the deletion receipt now reports the data plane as cleared as soon as the data plane acknowledges configuration that no longer carries the deleted project. Before, that data plane stayed clearing indefinitely.
Changed in v0.6.0 (bug fixes): Deleting a project now also deletes its project fallback overrides, so a project created later with the same ID starts with none. The upgrade removes overrides left behind by projects deleted earlier, unless a new project already uses the same ID: that project keeps them, and an admin who doesn't want them removes them on the Fallback page.
soft-delete rename; returns Empty, so the old success/deleted_at response fields go away
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project slug to soft-delete. |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the project was deleted. |
deleted_at | no | When the soft delete took effect. |
clearing_dataplanes | no | The data planes whose label for this project the delete removed, ascending (fraser#9424). Each of them serves the configuration it last pulled until its next pull lands, so this names what is now clearing rather than what has cleared; GetProjectDeletionImpact reports how far each one has got. |
{"signatures":{"go":"func (x *AdminClient) DeleteProject(ctx context.Context, req *adminv1.DeleteProjectRequest) (*adminv1.DeleteProjectResponse, error)","python":"delete_project(req: admin_pb2.DeleteProjectRequest) -\u003e DeleteProjectResponse","typescript":"deleteProject(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.DeleteProjectRequestSchema\u003e): Promise\u003cDeleteProjectResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.DeleteProjectRequest{}\n\n\tresp, err := client.Admin().DeleteProject(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/deleteproject\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.DeleteProjectRequest()\ntry:\n result = client.admin.delete_project(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.deleteProject(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}","slug":"delete-project"}
List project dataplanes
Changed in v0.7.0 (new features): You can now ask which data planes serve a project. ListProjectDataplanes answers with the data planes carrying the project's label and where each one stands in serving it, and a project no data plane serves answers an empty list rather than an error. It answers on every deployment, unlike ListProjectGatewayMembers beside it, which stays Enterprise-only and keyed on gateways.
Changed in v0.7.0 (new features): Each project label now says when that data plane first answered a request for the project successfully, in a new verified_at field. It is per project and data plane, so another project's traffic on the same data plane never sets it, and applying a label again clears it until the next success. Each label also reports the config pull before it, as target_revision, held_revision and config_current.
What it does: List the data planes serving a project, which is the project's serving view (fraser#9573). The answer comes from the project labels a data plane carries (dataplane_projects, fraser#8587): a data plane serves the configuration of every project labeled on it, so the label set IS the set of data planes serving the project. The gateway a data plane hosts does not enter the question, which is why this read answers where ListProjectGatewayMembers does not. Available on EVERY deployment shape. A data plane carries project labels on SaaS exactly as it does on Enterprise, so nothing here is gated on the deployment product — the Enterprise-only surface is several gateways serving one project, and this RPC names no gateway. A project that no data plane serves answers an EMPTY list rather than an error. That state is normal: a project is created without infrastructure and stays unlabeled until a platform admin labels a data plane with it. Responses carry identity and state only, never credential material.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project whose data planes to list. Carries the project_id_field marker so a project_owner caller is authorized against the project it names. |
Response fields:
| Field | Required | Description |
|---|---|---|
dataplanes | no | One line per data plane carrying the project's label, ascending by dataplane_id. Empty for a project no data plane serves, which is a valid state rather than an error. |
{"signatures":{"go":"func (x *AdminClient) ListProjectDataplanes(ctx context.Context, req *adminv1.ListProjectDataplanesRequest) (*adminv1.ListProjectDataplanesResponse, error)","python":"list_project_dataplanes(req: admin_pb2.ListProjectDataplanesRequest) -\u003e ListProjectDataplanesResponse","typescript":"listProjectDataplanes(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectDataplanesRequestSchema\u003e): Promise\u003cListProjectDataplanesResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../dataplanes\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectDataplanesRequest{}\n\n\tresp, err := client.Admin().ListProjectDataplanes(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojectdataplanes\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectDataplanesRequest()\ntry:\n result = client.admin.list_project_dataplanes(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjectDataplanes(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../dataplanes\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"App Developer (API key)","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/dataplanes","slug":"list-project-dataplanes"}
Get project deletion impact
Changed in v0.11.0 (new features): GetProjectDeletionImpact previews what deleting a live project removes: the project's id, and the number of users, model assignments, API keys, revoked API keys, settings, fallback policies, provider grants, MCP server grants, MCP profiles, OIDC contracts and role bindings granted directly at the project's scope. All counts except users and model assignments use the delete's own rules, and all twelve fields are empty after the delete.
Changed in v0.7.0 (new features): GetProjectDeletionImpact reads what deleting a project costs, and how far a delete under way has got. Before the delete it names every data plane serving the project. After it, each reads CLEARING until every gateway it hosted for the project acknowledged the zeroized configuration, then CLEARED with the time the last did. One still hosting a gateway joined to the project stays CLEARING; one carrying neither a membership nor a joined gateway is absent.
Changed in v0.7.0 (bug fixes): Deleting a project that shares a gateway with another project no longer stops that gateway serving the other project, and the deletion receipt now reports the data plane as cleared as soon as the data plane acknowledges configuration that no longer carries the deleted project. Before, that data plane stayed clearing indefinitely.
What it does: Report what deleting a project takes off the fleet, and how far that has got (fraser#9424). One call answers both halves of the operation: before the delete it names every data plane carrying the project's label, which is the blast radius an operator confirms; after it, the same data planes say whether each has cleared the project's configuration or is still serving what it last pulled. The reading is per data plane rather than per gateway (fraser#8587). A data plane hosting several of the project's gateways is one line, and it reads CLEARED only once every one of them has acknowledged the zeroized revision. What puts a data plane in the receipt is a membership this delete unwound, or a gateway still joined to the project. A gateway joined with no membership behind it is a stranded re-attach and holds its data plane at CLEARING, because it serves the project and has acknowledged nothing for it. What this RPC cannot see after the delete is a data plane that carried the label with neither of those left on it. Nothing sent it a zeroized revision, so there is no acknowledgement to wait for, and it leaves the receipt with the project. The membership ledger is what records the unwind, and a label is not a substitute for one. The receipt covers THIS delete and no earlier one. A gateway that left the project before it was deleted took the project off its data plane then, and the delete found nothing there to remove, so that data plane is absent from the receipt exactly as it was absent from the confirmation. A data plane is named by where its gateway sits when the receipt is read, not by where the membership was when it detached, because the ledger records the gateway and the gateway records the data plane (fraser#8587 re-keys that). Moving a gateway between data planes after the delete therefore moves its line with it. Moving a gateway also tears down its configuration on the data plane it leaves, so the one that ends up named is never a data plane still serving the project; what is lost is which data plane acknowledged. A slug deleted and then recreated reports the NEW project: this reads the live incarnation whenever one exists, so a receipt has to be read before the slug is reused. Compare project_uuid with the id read before the delete to detect this. While the project is live the response also previews what the delete removes (fraser#6371): the project's id and five counts, read in one snapshot. In JSON a zero count is left out, so a missing count is 0.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project slug whose deletion is being previewed or verified. A deleted slug is a valid argument: reading the receipt is the point. |
Response fields:
| Field | Required | Description |
|---|---|---|
dataplanes | no | One line per data plane, by data plane id. Empty for a project no data plane serves, which is a valid state rather than an error: deleting it takes nothing off the fleet. |
project_live | no | True while the project exists. False reports a deletion that has already happened, so every line is CLEARING or CLEARED. |
project_uuid | output-only | The id of the live project. The slug is reusable, so this names the project a delete would remove. Set only while project_live is true. |
member_count | output-only | The project's members, not counting deleted users. Banned users count. Set only while project_live is true. |
model_assignment_count | output-only | The project's model assignments, not counting a model that no longer exists. Set only while project_live is true. |
api_key_count | output-only | The live keys the delete revokes: those ListApiKeys reports as API_KEY_STATUS_ACTIVE or API_KEY_STATUS_INACTIVE. Set only while project_live is true. |
revoked_api_key_count | output-only | The keys revoked before the delete, which the delete hides: those ListApiKeys reports as API_KEY_STATUS_REVOKED, and as API_KEY_STATUS_DELETED after the delete. They stay on the revocation list. Set only while project_live is true. |
setting_count | output-only | The project's settings, which the delete removes. Set only while project_live is true. |
fallback_policy_count | output-only | The project's fallback policies, active or not, which the delete removes together with their entries. Set only while project_live is true. |
provider_allowlist_count | output-only | The providers granted to the project, which the delete removes. Set only while project_live is true. |
mcp_server_grant_count | output-only | The MCP servers granted to the project, which the delete removes. Set only while project_live is true. |
mcp_profile_count | output-only | The live MCP profiles of the project's users, which the delete soft-deletes together with their backends. Set only while project_live is true. |
oidc_config_count | output-only | The project's OIDC contract, 0 or 1, which the delete removes. Set only while project_live is true. |
rbac_binding_count | output-only | The role bindings at the project's scope that were granted directly, to a user or a group, which the delete removes. The binding each member holds through membership is not counted here, because member_count already reports it. Set only while project_live is true. |
{"signatures":{"go":"func (x *AdminClient) GetProjectDeletionImpact(ctx context.Context, req *adminv1.GetProjectDeletionImpactRequest) (*adminv1.GetProjectDeletionImpactResponse, error)","python":"get_project_deletion_impact(req: admin_pb2.GetProjectDeletionImpactRequest) -\u003e GetProjectDeletionImpactResponse","typescript":"getProjectDeletionImpact(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetProjectDeletionImpactRequestSchema\u003e): Promise\u003cGetProjectDeletionImpactResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../deletion-impact\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetProjectDeletionImpactRequest{}\n\n\tresp, err := client.Admin().GetProjectDeletionImpact(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getprojectdeletionimpact\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetProjectDeletionImpactRequest()\ntry:\n result = client.admin.get_project_deletion_impact(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getProjectDeletionImpact(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../deletion-impact\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/deletion-impact","slug":"get-project-deletion-impact"}
Add project member
Changed in v0.10.0 (behaviour changes): Removing users from a project or demoting them protects assignments of the built-in Project Owner role held by users who have not been deleted. Admin memberships, custom roles and directly granted permissions do not count as Project Owner assignments.
Changed in v0.8.0 (bug fixes): Project default settings, project membership changes, the request-log mode, and rate-limit policies moved to another target now reach your gateways within the usual update cycle. They were previously saved but not pushed, so keys kept an old rate limit or fallback, a removed member kept the project's shared provider keys, and a moved policy kept limiting its old keys. A project-wide rate limit is also now enforced on keys with no settings of their own.
Changed in v0.1.5 (security updates): Adding a member to a project now rejects an identity that does not exist, instead of recording a membership and role assignment against an unknown id: records that were inert until someone was later created with the same id and inherited the access. Both API surfaces enforce this.
Changed in v0.1.5 (bug fixes): Adding a project member now fails with a 404 error when the given identity does not exist, instead of creating the membership and its RBAC binding anyway, records a user registering later with the same ID could inherit. The check and write run in one statement, so a concurrent identity deletion cannot slip through. The same call updates an existing member's role, and that path now also fails with a 404 when the member's identity was deleted. Member removal is unaffected, so cleanup of such rows still works.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to add the member to. |
user_id | no | User ID to add as a member. |
role | no | Role to grant: "admin" or "member". |
Response fields:
| Field | Required | Description |
|---|---|---|
member | no | The created membership. |
{"signatures":{"go":"func (x *AdminClient) AddProjectMember(ctx context.Context, req *adminv1.AddProjectMemberRequest) (*adminv1.AddProjectMemberResponse, error)","python":"add_project_member(req: admin_pb2.AddProjectMemberRequest) -\u003e AddProjectMemberResponse","typescript":"addProjectMember(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.AddProjectMemberRequestSchema\u003e): Promise\u003cAddProjectMemberResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../members\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"user_id\": \"...\",\n \"role\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.AddProjectMemberRequest{}\n\n\tresp, err := client.Admin().AddProjectMember(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/addprojectmember\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.AddProjectMemberRequest()\ntry:\n result = client.admin.add_project_member(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.addProjectMember(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../members\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"user_id\": \"...\",\n \"role\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/members","slug":"add-project-member"}
List project members
Changed in v0.1.5 (bug fixes): Listing a project's members now includes people whose access comes from a role or permission granted on that project, not only those added directly. Both let someone into the project, but only direct membership appeared on the list, so it under-reported who could reach the project, wrong for an access review or offboarding. Someone listed this way has no membership record to change, so they are reported without one, and their access is removed where it was granted rather than from the member list.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project whose members to list. |
Response fields:
| Field | Required | Description |
|---|---|---|
members | no | All members of the project. |
{"signatures":{"go":"func (x *AdminClient) ListProjectMembers(ctx context.Context, req *adminv1.ListProjectMembersRequest) (*adminv1.ListProjectMembersResponse, error)","python":"list_project_members(req: admin_pb2.ListProjectMembersRequest) -\u003e ListProjectMembersResponse","typescript":"listProjectMembers(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectMembersRequestSchema\u003e): Promise\u003cListProjectMembersResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../members\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectMembersRequest{}\n\n\tresp, err := client.Admin().ListProjectMembers(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojectmembers\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectMembersRequest()\ntry:\n result = client.admin.list_project_members(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjectMembers(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../members\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/members","slug":"list-project-members"}
Update project member
Changed in v0.10.0 (behaviour changes): Removing users from a project or demoting them protects assignments of the built-in Project Owner role held by users who have not been deleted. Admin memberships, custom roles and directly granted permissions do not count as Project Owner assignments.
Changed in v0.3.0 (security updates): A project can no longer be left with no administrator. Demoting or removing a project's last admin through the admin or tenancy member APIs is now refused with FailedPrecondition; the mutation is allowed again as soon as a second admin exists. Previously either call could strip the final admin and orphan the project, leaving no one able to manage its members. A project whose ownership is held only through a manual role grant (not a member row) is unaffected, and revoking that grant is still done separately.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project the member belongs to. |
user_id | no | User ID of the member to update. |
role | no | New role: "admin" or "member". |
Response fields:
| Field | Required | Description |
|---|---|---|
member | no | The updated membership. |
{"signatures":{"go":"func (x *AdminClient) UpdateProjectMember(ctx context.Context, req *adminv1.UpdateProjectMemberRequest) (*adminv1.UpdateProjectMemberResponse, error)","python":"update_project_member(req: admin_pb2.UpdateProjectMemberRequest) -\u003e UpdateProjectMemberResponse","typescript":"updateProjectMember(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpdateProjectMemberRequestSchema\u003e): Promise\u003cUpdateProjectMemberResponse\u003e","curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../members/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"role\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpdateProjectMemberRequest{}\n\n\tresp, err := client.Admin().UpdateProjectMember(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/updateprojectmember\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpdateProjectMemberRequest()\ntry:\n result = client.admin.update_project_member(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.updateProjectMember(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PATCH \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../members/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"role\": \"...\"\n }'"},"persona":"Admin","httpVerb":"PATCH","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/members/{user_id}","slug":"update-project-member"}
Remove project member
Changed in v0.10.0 (behaviour changes): Removing users from a project or demoting them protects assignments of the built-in Project Owner role held by users who have not been deleted. Admin memberships, custom roles and directly granted permissions do not count as Project Owner assignments.
Changed in v0.8.0 (bug fixes): Project default settings, project membership changes, the request-log mode, and rate-limit policies moved to another target now reach your gateways within the usual update cycle. They were previously saved but not pushed, so keys kept an old rate limit or fallback, a removed member kept the project's shared provider keys, and a moved policy kept limiting its old keys. A project-wide rate limit is also now enforced on keys with no settings of their own.
Changed in v0.3.0 (security updates): A project can no longer be left with no administrator. Demoting or removing a project's last admin through the admin or tenancy member APIs is now refused with FailedPrecondition; the mutation is allowed again as soon as a second admin exists. Previously either call could strip the final admin and orphan the project, leaving no one able to manage its members. A project whose ownership is held only through a manual role grant (not a member row) is unaffected, and revoking that grant is still done separately.
identity_id replaces user_id; returns Empty, so the old success response field goes away
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to remove the member from. |
user_id | no | User ID of the member to remove. |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the member was removed. |
{"signatures":{"go":"func (x *AdminClient) RemoveProjectMember(ctx context.Context, req *adminv1.RemoveProjectMemberRequest) (*adminv1.RemoveProjectMemberResponse, error)","python":"remove_project_member(req: admin_pb2.RemoveProjectMemberRequest) -\u003e RemoveProjectMemberResponse","typescript":"removeProjectMember(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.RemoveProjectMemberRequestSchema\u003e): Promise\u003cRemoveProjectMemberResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../members/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.RemoveProjectMemberRequest{}\n\n\tresp, err := client.Admin().RemoveProjectMember(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/removeprojectmember\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.RemoveProjectMemberRequest()\ntry:\n result = client.admin.remove_project_member(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.removeProjectMember(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../members/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/members/{user_id}","slug":"remove-project-member"}
Ensure admin project membership
What it does: Records the intent to grant an email a role on a project (#6119). At onboarding/provisioning time the target identity row usually does not exist yet (SSO users are created lazily at first login), so the grant is parked by email and materialized at first login via ResolvePendingProjectMemberships. If the identity already exists the grant is written straight to project_members instead. Idempotent.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to grant membership on. |
email | no | Email of the intended member. Matched case-insensitively against the identity at resolution time. |
role | no | Role to grant: "admin" or "member". |
Response fields:
| Field | Required | Description |
|---|---|---|
enqueued | no | True when the grant was parked as a pending row (the identity did not exist yet and will be resolved at first login); false when it was written directly to project_members because the identity already existed. |
{"signatures":{"go":"func (x *AdminClient) EnsureAdminProjectMembership(ctx context.Context, req *adminv1.EnsureAdminProjectMembershipRequest) (*adminv1.EnsureAdminProjectMembershipResponse, error)","python":"ensure_admin_project_membership(req: admin_pb2.EnsureAdminProjectMembershipRequest) -\u003e EnsureAdminProjectMembershipResponse","typescript":"ensureAdminProjectMembership(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.EnsureAdminProjectMembershipRequestSchema\u003e): Promise\u003cEnsureAdminProjectMembershipResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../pending-members\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"email\": \"...\",\n \"role\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.EnsureAdminProjectMembershipRequest{}\n\n\tresp, err := client.Admin().EnsureAdminProjectMembership(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/ensureadminprojectmembership\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.EnsureAdminProjectMembershipRequest()\ntry:\n result = client.admin.ensure_admin_project_membership(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.ensureAdminProjectMembership(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../pending-members\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"email\": \"...\",\n \"role\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/pending-members","slug":"ensure-admin-project-membership"}
Resolve pending project memberships
What it does: Materializes every pending email-keyed grant for (customer_id, email) into real project_members rows for user_id, then clears the resolved pending rows (#6119). Idempotent and cheap to call on every login: with no pending rows it is a no-op.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
email | no | Email whose pending grants to resolve. Matched case-insensitively. |
user_id | no | Identity id (authn.user.id) to materialize the memberships onto. |
Response fields:
| Field | Required | Description |
|---|---|---|
resolved_count | no | Number of pending grants materialized into project_members rows. |
{"signatures":{"go":"func (x *AdminClient) ResolvePendingProjectMemberships(ctx context.Context, req *adminv1.ResolvePendingProjectMembershipsRequest) (*adminv1.ResolvePendingProjectMembershipsResponse, error)","python":"resolve_pending_project_memberships(req: admin_pb2.ResolvePendingProjectMembershipsRequest) -\u003e ResolvePendingProjectMembershipsResponse","typescript":"resolvePendingProjectMemberships(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ResolvePendingProjectMembershipsRequestSchema\u003e): Promise\u003cResolvePendingProjectMembershipsResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../pending-members:resolve\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"email\": \"...\",\n \"user_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ResolvePendingProjectMembershipsRequest{}\n\n\tresp, err := client.Admin().ResolvePendingProjectMemberships(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/resolvependingprojectmemberships\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ResolvePendingProjectMembershipsRequest()\ntry:\n result = client.admin.resolve_pending_project_memberships(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.resolvePendingProjectMemberships(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../pending-members:resolve\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"email\": \"...\",\n \"user_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/pending-members:resolve","slug":"resolve-pending-project-memberships"}
Ensure default project membership
Changed in v0.11.0 (new features): EnsureDefaultProjectMembership adds a user to the Users of their organization's default project when they are not in it yet, and reports whether they joined. It never changes an existing role, skips a banned user or one SCIM blocks from signing in, and writes an AUTO_JOIN_DEFAULT_PROJECT audit record when the user joins. It needs the admin management key or the project.members.add permission.
What it does: Adds user_id to the customer's default project as a member when the user has no membership there (#6526). It creates the default project first when it is missing. It never changes the role of an existing member, and it skips a user whom SCIM blocks from signing in. Idempotent: a repeat call leaves the same state and returns joined=false.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
user_id | no | Identity id (authn.user.id) to add to the default project. |
Response fields:
| Field | Required | Description |
|---|---|---|
joined | no | True when this call added the user to the default project; false when the user was already a member or SCIM blocks them from signing in. |
{"signatures":{"go":"func (x *AdminClient) EnsureDefaultProjectMembership(ctx context.Context, req *adminv1.EnsureDefaultProjectMembershipRequest) (*adminv1.EnsureDefaultProjectMembershipResponse, error)","python":"ensure_default_project_membership(req: admin_pb2.EnsureDefaultProjectMembershipRequest) -\u003e EnsureDefaultProjectMembershipResponse","typescript":"ensureDefaultProjectMembership(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.EnsureDefaultProjectMembershipRequestSchema\u003e): Promise\u003cEnsureDefaultProjectMembershipResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/default/members:ensure\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"user_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.EnsureDefaultProjectMembershipRequest{}\n\n\tresp, err := client.Admin().EnsureDefaultProjectMembership(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/ensuredefaultprojectmembership\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.EnsureDefaultProjectMembershipRequest()\ntry:\n result = client.admin.ensure_default_project_membership(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.ensureDefaultProjectMembership(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/default/members:ensure\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"user_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/projects/default/members:ensure","slug":"ensure-default-project-membership"}
List models
Request fields:
| Field | Required | Description |
|---|---|---|
only_enabled | no | If true, return only enabled models. |
Response fields:
| Field | Required | Description |
|---|---|---|
models | no | Catalog models matching the request. |
{"signatures":{"go":"func (x *AdminClient) ListModels(ctx context.Context, req *adminv1.ListModelsRequest) (*adminv1.ListModelsResponse, error)","python":"list_models(req: admin_pb2.ListModelsRequest) -\u003e ListModelsResponse","typescript":"listModels(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListModelsRequestSchema\u003e): Promise\u003cListModelsResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListModelsRequest{}\n\n\tresp, err := client.Admin().ListModels(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listmodels\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListModelsRequest()\ntry:\n result = client.admin.list_models(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listModels(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/models","slug":"list-models"}
Get model
Request fields:
| Field | Required | Description |
|---|---|---|
model_id | no | Catalog entry UUID to fetch. |
Response fields:
| Field | Required | Description |
|---|---|---|
model | no | The requested model. |
{"signatures":{"go":"func (x *AdminClient) GetModel(ctx context.Context, req *adminv1.GetModelRequest) (*adminv1.GetModelResponse, error)","python":"get_model(req: admin_pb2.GetModelRequest) -\u003e GetModelResponse","typescript":"getModel(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetModelRequestSchema\u003e): Promise\u003cGetModelResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/models/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetModelRequest{}\n\n\tresp, err := client.Admin().GetModel(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getmodel\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetModelRequest()\ntry:\n result = client.admin.get_model(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getModel(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/models/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/models/{model_id}","slug":"get-model"}
Get model usage
Changed in v0.8.0 (new features): Admins can see which models their organization uses retire soon, and which projects and API keys still call them. A model whose retirement date has passed is included, flagged as retired, while the organization still calls it. Results cover only your organization.
What it does: Lists the projects and API keys in the caller's organization that called a catalogue model inside a bounded window, and when each was last seen (fraser#10229). Organization-scoped, never platform-wide: a caller with no organization binding is denied, and a project-tier key sees only its own project.
Request fields:
| Field | Required | Description |
|---|---|---|
model_id | no | Catalog entry UUID (ai_models id) to report usage for. |
window_days | no | Look-back window in whole UTC days (plus today). Defaults to 30 when unset; must be between 1 and 365. |
Response fields:
| Field | Required | Description |
|---|---|---|
model_id | no | Echo of the requested model. |
window_days | no | The effective window, after defaulting. |
projects | no | Projects that called the model, most recently seen first. |
api_keys | no | API keys that called the model, most recently seen first. |
{"signatures":{"go":"func (x *AdminClient) GetModelUsage(ctx context.Context, req *adminv1.GetModelUsageRequest) (*adminv1.GetModelUsageResponse, error)","python":"get_model_usage(req: admin_pb2.GetModelUsageRequest) -\u003e GetModelUsageResponse","typescript":"getModelUsage(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetModelUsageRequestSchema\u003e): Promise\u003cGetModelUsageResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/models/01H.../usage\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetModelUsageRequest{}\n\n\tresp, err := client.Admin().GetModelUsage(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getmodelusage\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetModelUsageRequest()\ntry:\n result = client.admin.get_model_usage(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getModelUsage(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/models/01H.../usage\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/models/{model_id}/usage","slug":"get-model-usage"}
List retiring models
Changed in v0.8.0 (new features): Admins can see which models their organization uses retire soon, and which projects and API keys still call them. A model whose retirement date has passed is included, flagged as retired, while the organization still calls it. Results cover only your organization.
What it does: Lists the catalogue models the caller's organization is actually using (called in the last 30 days) whose retirement_date is inside the requested window (fraser#10229). Computed server-side from the catalogue lifecycle verdict and the usage rollups. Organization-scoped, never platform-wide.
Request fields:
| Field | Required | Description |
|---|---|---|
window_days | no | Look-ahead window in days from today for metadata.retirement_date. Defaults to 60 when unset; must be between 1 and 365. |
Response fields:
| Field | Required | Description |
|---|---|---|
window_days | no | The effective retirement window, after defaulting. |
usage_window_days | no | The usage window that defines "in use" (30 days). |
models | no | Models in use that retire inside the window, soonest first. |
{"signatures":{"go":"func (x *AdminClient) ListRetiringModels(ctx context.Context, req *adminv1.ListRetiringModelsRequest) (*adminv1.ListRetiringModelsResponse, error)","python":"list_retiring_models(req: admin_pb2.ListRetiringModelsRequest) -\u003e ListRetiringModelsResponse","typescript":"listRetiringModels(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListRetiringModelsRequestSchema\u003e): Promise\u003cListRetiringModelsResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/retiring-models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListRetiringModelsRequest{}\n\n\tresp, err := client.Admin().ListRetiringModels(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listretiringmodels\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListRetiringModelsRequest()\ntry:\n result = client.admin.list_retiring_models(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listRetiringModels(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/retiring-models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/retiring-models","slug":"list-retiring-models"}
List catalog providers
Changed in v0.6.0 (new features): Provider reads have a new field, has_credential: true when the provider's platform key is stored, false when it is not, and unset when the check could not run (the read still succeeds). ListProviders and GetProvider also accept a customer_id, and optionally a project_id within it, which returns the same providers without the key suffix or internal metadata.
Request fields:
| Field | Required | Description |
|---|---|---|
include_disabled | no | Return disabled providers alongside enabled ones. Defaults false, which is the enabled-only view every interactive caller expects. A catalogue SYNC must set it. Without the full picture it cannot tell a disabled provider from an absent one, so it re-proposes every disabled row as new on each run -- and, with disable-absent enabled, would act on that. The store has always supported this (catalog.Store.ListProviders takes includeDisabled); only the admin surface could not ask for it. |
Response fields:
| Field | Required | Description |
|---|---|---|
providers | no | Providers in catalog order: enabled ones only, or the whole catalogue when the request set include_disabled. |
{"signatures":{"go":"func (x *AdminClient) ListCatalogProviders(ctx context.Context, req *adminv1.ListCatalogProvidersRequest) (*adminv1.ListCatalogProvidersResponse, error)","python":"list_catalog_providers(req: admin_pb2.ListCatalogProvidersRequest) -\u003e ListCatalogProvidersResponse","typescript":"listCatalogProviders(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListCatalogProvidersRequestSchema\u003e): Promise\u003cListCatalogProvidersResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/providers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListCatalogProvidersRequest{}\n\n\tresp, err := client.Admin().ListCatalogProviders(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listcatalogproviders\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListCatalogProvidersRequest()\ntry:\n result = client.admin.list_catalog_providers(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listCatalogProviders(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/providers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/catalog/providers","slug":"list-catalog-providers"}
List catalog models
Changed in v0.7.0 (new features): Catalog model lists can be paged with page, and support search, mode, modality, context-window and price filters, sorting and snapshot grouping. Paged lists leave out models whose provider is disabled unless include_disabled is set.
Changed in v0.7.0 (deprecations): A catalog model list that sets only provider_id or include_disabled still returns the full catalog, but is deprecated and will return one page in a later release. Setting any other field returns one page.
Request fields:
| Field | Required | Description |
|---|---|---|
provider_id | no | Filter to models belonging to this provider. Empty includes all providers. |
include_disabled | no | Include disabled models. Paginated reads otherwise also leave out models belonging to disabled providers; the unpaginated response does not. |
page | no | Pagination. A request that sets none of the fields below keeps the deprecated unpaginated response: every matching model, ordered by provider then model. That response is deprecated and will be removed; send page and follow page.next_page_token. Page size defaults to 20 items when page is set; maximum size 5000. order_by supports name, context_window, input_price, output_price (asc/desc). Empty order_by prioritizes first-party providers, release date descending, then model name. page.filter is unsupported; use the typed fields below. |
search | no | Ordered, case-insensitive search across model and provider names/labels. |
mode | no | undocumented |
input_modality | no | undocumented |
output_modality | no | undocumented |
model_ids | no | Additional selection, not an authorization grant. Empty ids selects no models. |
context_window | no | undocumented |
input_price | no | undocumented |
output_price | no | undocumented |
group_snapshots | no | Count a base model and its snapshots as one item, before pagination. |
skip | no | Skip items for numbered-page navigation. Cannot be combined with page_token. |
Response fields:
| Field | Required | Description |
|---|---|---|
models | no | Flat results; for grouped requests use groups instead. |
page | no | undocumented |
groups | no | undocumented |
total_count | no | Filtered model count, or group/standalone count when group_snapshots is set. |
{"signatures":{"go":"func (x *AdminClient) ListCatalogModels(ctx context.Context, req *adminv1.ListCatalogModelsRequest) (*adminv1.ListCatalogModelsResponse, error)","python":"list_catalog_models(req: admin_pb2.ListCatalogModelsRequest) -\u003e ListCatalogModelsResponse","typescript":"listCatalogModels(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListCatalogModelsRequestSchema\u003e): Promise\u003cListCatalogModelsResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListCatalogModelsRequest{}\n\n\tresp, err := client.Admin().ListCatalogModels(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listcatalogmodels\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListCatalogModelsRequest()\ntry:\n result = client.admin.list_catalog_models(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listCatalogModels(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/catalog/models","slug":"list-catalog-models"}
List mcp catalog servers
Request fields:
| Field | Required | Description |
|---|---|---|
include_disabled | no | When true, include is_enabled=false entries. |
Response fields:
| Field | Required | Description |
|---|---|---|
servers | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) ListMcpCatalogServers(ctx context.Context, req *adminv1.ListMcpCatalogServersRequest) (*adminv1.ListMcpCatalogServersResponse, error)","python":"list_mcp_catalog_servers(req: admin_pb2.ListMcpCatalogServersRequest) -\u003e ListMcpCatalogServersResponse","typescript":"listMcpCatalogServers(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListMcpCatalogServersRequestSchema\u003e): Promise\u003cListMcpCatalogServersResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/mcp/catalog/servers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListMcpCatalogServersRequest{}\n\n\tresp, err := client.Admin().ListMcpCatalogServers(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listmcpcatalogservers\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListMcpCatalogServersRequest()\ntry:\n result = client.admin.list_mcp_catalog_servers(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listMcpCatalogServers(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/mcp/catalog/servers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/mcp/catalog/servers","slug":"list-mcp-catalog-servers"}
Upsert catalog provider
Changed in v0.6.0 (new features): CreateProvider adds a provider and returns AlreadyExists if the id is taken, and DeleteProviderCredential removes a provider's platform key. UpsertProvider now needs display_name, base_url and a canonical id only when it creates the provider, so {id, is_enabled} toggles an existing one.
Changed in v0.6.0 (new features): UpsertProvider has a new field, remove_metadata_keys, that removes the named top-level keys from the provider's metadata. A null value in metadata is still stored as sent. credential and credential_suffix cannot be removed this way.
Changed in v0.5.0 (new features): Catalog audit entries now say whether a write came from a batch. A sync run's several hundred UPSERT rows carry batched: true in their metadata and interactive edits carry batched: false, so the audit view can be filtered to just the changes a person made.
What it does: Admin-key catalog WRITES (fraser#8451). The identity-authenticated CatalogService.UpsertProvider/UpsertModel are mounted on the IA mux, which accepts only a session token or an <address>.<body> public.api_keys key -- so a platform admin_api_keys key can never reach them. That is the same wall #6025 hit for READS, solved the same way: expose the operation behind the admin auth path. These delegate to catalog.Server, so validation, metadata handling, suppress_route_regen semantics and the per-gateway fan-out are the SAME code as the identity surface rather than a parallel implementation. The motivating caller is the catalog-sync CronJob, whose only credential on a provisioned management plane is that plane's admin key.
Request fields:
| Field | Required | Description |
|---|---|---|
provider | no | The provider to create or update. Reuses the identity surface's message so the two paths cannot drift in what a provider IS. |
Response fields:
| Field | Required | Description |
|---|---|---|
provider | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) UpsertCatalogProvider(ctx context.Context, req *adminv1.UpsertCatalogProviderRequest) (*adminv1.UpsertCatalogProviderResponse, error)","python":"upsert_catalog_provider(req: admin_pb2.UpsertCatalogProviderRequest) -\u003e UpsertCatalogProviderResponse","typescript":"upsertCatalogProvider(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpsertCatalogProviderRequestSchema\u003e): Promise\u003cUpsertCatalogProviderResponse\u003e","curl":"curl -X PUT \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/providers/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"provider\": {}\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpsertCatalogProviderRequest{}\n\n\tresp, err := client.Admin().UpsertCatalogProvider(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/upsertcatalogprovider\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpsertCatalogProviderRequest()\ntry:\n result = client.admin.upsert_catalog_provider(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.upsertCatalogProvider(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PUT \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/providers/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"provider\": {}\n }'"},"persona":"Admin","httpVerb":"PUT","httpPath":"/admin/v1/catalog/providers/{provider.id}","slug":"upsert-catalog-provider"}
Upsert catalog model
Changed in v0.10.0 (new features): UpsertModel takes clear_fields, to clear stored values such as a price, the context window or the backend URLs, and remove_metadata_keys, to remove metadata keys. A request that sets neither works as before.
Changed in v0.5.0 (new features): Catalog audit entries now say whether a write came from a batch. A sync run's several hundred UPSERT rows carry batched: true in their metadata and interactive edits carry batched: false, so the audit view can be filtered to just the changes a person made.
Request fields:
| Field | Required | Description |
|---|---|---|
model | no | See UpsertCatalogProviderRequest.provider. |
Response fields:
| Field | Required | Description |
|---|---|---|
model | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) UpsertCatalogModel(ctx context.Context, req *adminv1.UpsertCatalogModelRequest) (*adminv1.UpsertCatalogModelResponse, error)","python":"upsert_catalog_model(req: admin_pb2.UpsertCatalogModelRequest) -\u003e UpsertCatalogModelResponse","typescript":"upsertCatalogModel(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpsertCatalogModelRequestSchema\u003e): Promise\u003cUpsertCatalogModelResponse\u003e","curl":"curl -X PUT \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"model\": {}\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpsertCatalogModelRequest{}\n\n\tresp, err := client.Admin().UpsertCatalogModel(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/upsertcatalogmodel\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpsertCatalogModelRequest()\ntry:\n result = client.admin.upsert_catalog_model(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.upsertCatalogModel(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PUT \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"model\": {}\n }'"},"persona":"Admin","httpVerb":"PUT","httpPath":"/admin/v1/catalog/models","slug":"upsert-catalog-model"}
Regenerate catalog routes
What it does: Publish the catalogue to the data plane: one GLOBAL_ROUTES regeneration. The counterpart to suppress_route_regen on the two upserts above. A batch caller suppresses per-write regeneration and calls this ONCE at the end, so ~700 entries cost one fan-out rather than ~700. Deliberately takes NO caller-supplied scope. The underlying trigger must carry the "system" sentinel or the configurator narrows delivery to the caller's own customer, stranding every other workspace on the previous catalogue -- and the catalogue is global (ai_providers is keyed by name, ai_models is not customer-scoped). Server-side only, so a caller cannot get that wrong.
Request fields:
| Field | Required | Description |
|---|---|---|
reason | no | Free-text note recorded in the regeneration log line, e.g. "catalog-sync 2026-09-09". Optional; no effect on what is regenerated. |
Response fields:
| Field | Required | Description |
|---|---|---|
regenerated | no | False when no route regenerator is wired (a management plane running without a configurator). The call is not an error in that case -- there is simply nothing to publish through -- but a caller that wrote entries needs to know they are committed and unpublished. |
{"signatures":{"go":"func (x *AdminClient) RegenerateCatalogRoutes(ctx context.Context, req *adminv1.RegenerateCatalogRoutesRequest) (*adminv1.RegenerateCatalogRoutesResponse, error)","python":"regenerate_catalog_routes(req: admin_pb2.RegenerateCatalogRoutesRequest) -\u003e RegenerateCatalogRoutesResponse","typescript":"regenerateCatalogRoutes(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.RegenerateCatalogRoutesRequestSchema\u003e): Promise\u003cRegenerateCatalogRoutesResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/catalog:regenerate-routes\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"reason\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.RegenerateCatalogRoutesRequest{}\n\n\tresp, err := client.Admin().RegenerateCatalogRoutes(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/regeneratecatalogroutes\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.RegenerateCatalogRoutesRequest()\ntry:\n result = client.admin.regenerate_catalog_routes(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.regenerateCatalogRoutes(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/catalog:regenerate-routes\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"reason\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/catalog:regenerate-routes","slug":"regenerate-catalog-routes"}
Record catalog sync
Changed in v0.5.0 (new features): The catalog API can now record and read a management plane's catalog sync state: which published catalog version it last read, which one it is actually on, when each happened and who ran it. The same pair is on the admin API, so a scheduled job authenticating with a plane's admin key writes the same record an operator's own run does.
What it does: Catalog sync freshness (fraser#7951), admin-key half. Same wall, same shape as the writes above: the catalog-sync CronJob's only credential on a provisioned management plane is that plane's admin key, which cannot reach tars.catalog.v1.CatalogService at all. Both routes delegate to the same catalog.Server, so there is one record and one set of merge rules whichever surface wrote it -- a hand-run with a session token and a nightly job with an admin key update the same row. Two records would be worse than none: each would look stale whenever the other ran.
Request fields:
| Field | Required | Description |
|---|---|---|
run | no | The run to record. Reuses the identity surface's message so the two paths cannot drift in what a sync run IS, and so the merge rules documented on CatalogService.RecordCatalogSync are the only ones. |
Response fields:
| Field | Required | Description |
|---|---|---|
state | no | The merged record as persisted. Never null. |
{"signatures":{"go":"func (x *AdminClient) RecordCatalogSync(ctx context.Context, req *adminv1.RecordCatalogSyncRequest) (*adminv1.RecordCatalogSyncResponse, error)","python":"record_catalog_sync(req: admin_pb2.RecordCatalogSyncRequest) -\u003e RecordCatalogSyncResponse","typescript":"recordCatalogSync(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.RecordCatalogSyncRequestSchema\u003e): Promise\u003cRecordCatalogSyncResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/sync-state\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"run\": {}\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.RecordCatalogSyncRequest{}\n\n\tresp, err := client.Admin().RecordCatalogSync(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/recordcatalogsync\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.RecordCatalogSyncRequest()\ntry:\n result = client.admin.record_catalog_sync(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.recordCatalogSync(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/sync-state\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"run\": {}\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/catalog/sync-state","slug":"record-catalog-sync"}
Get catalog sync state
Changed in v0.5.0 (new features): The catalog API can now record and read a management plane's catalog sync state: which published catalog version it last read, which one it is actually on, when each happened and who ran it. The same pair is on the admin API, so a scheduled job authenticating with a plane's admin key writes the same record an operator's own run does.
Request body: None.
Response fields:
| Field | Required | Description |
|---|---|---|
state | no | Never null; both timestamps unset means no sync has ever been recorded. |
{"signatures":{"go":"func (x *AdminClient) GetCatalogSyncState(ctx context.Context, req *adminv1.GetCatalogSyncStateRequest) (*adminv1.GetCatalogSyncStateResponse, error)","python":"get_catalog_sync_state(req: admin_pb2.GetCatalogSyncStateRequest) -\u003e GetCatalogSyncStateResponse","typescript":"getCatalogSyncState(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetCatalogSyncStateRequestSchema\u003e): Promise\u003cGetCatalogSyncStateResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/sync-state\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetCatalogSyncStateRequest{}\n\n\tresp, err := client.Admin().GetCatalogSyncState(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getcatalogsyncstate\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetCatalogSyncStateRequest()\ntry:\n result = client.admin.get_catalog_sync_state(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getCatalogSyncState(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/sync-state\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/catalog/sync-state","slug":"get-catalog-sync-state"}
Plan catalog sync
Changed in v0.8.0 (new features): The model catalog can be synced through the admin API: preview what a sync would change, apply it in the background pinned to the exact documents previewed, and poll the run's progress. One sync runs at a time.
What it does: Fetches the published catalogue and returns what a sync would do, writing nothing to the catalogue itself. It DOES advance the sync-state record's checked_* fields, exactly as a CLI dry run does -- that record is what a dashboard's "new models available" indicator reads, and a preview is precisely "this plane checked the published catalogue". Hence models:EDIT rather than READ: the RPC writes the same record RecordCatalogSync writes, so it carries the same atom.
Request body: None.
Response fields:
| Field | Required | Description |
|---|---|---|
catalog_version | no | The published catalogue's exportedAt, verbatim; may be empty. |
sources | no | The documents this plan read, with their sha256 digests. Feed these back on ApplyCatalogSync so the apply is pinned to what was reviewed. |
providers | no | Only entries that would change; unchanged entries are counted below. |
models | no | undocumented |
skipped | no | undocumented |
absent | no | undocumented |
staged | no | undocumented |
unknown_providers | no | Providers the published models reference that exist neither in the published providers document nor on this plane. Their models are in skipped; this is the summary by name. |
warnings | no | Curation inconsistencies in the published documents. Never fatal. |
writes | no | How many entries an apply would write: len(providers)+len(models) above. |
unchanged_providers | no | undocumented |
unchanged_models | no | undocumented |
state | no | The sync-state record AFTER this plan recorded its checked_* fields. Returned so a dashboard refreshes its staleness indicator without a second round-trip. Never null. |
{"signatures":{"go":"func (x *AdminClient) PlanCatalogSync(ctx context.Context, req *adminv1.PlanCatalogSyncRequest) (*adminv1.PlanCatalogSyncResponse, error)","python":"plan_catalog_sync(req: admin_pb2.PlanCatalogSyncRequest) -\u003e PlanCatalogSyncResponse","typescript":"planCatalogSync(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.PlanCatalogSyncRequestSchema\u003e): Promise\u003cPlanCatalogSyncResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/sync:plan\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{}'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.PlanCatalogSyncRequest{}\n\n\tresp, err := client.Admin().PlanCatalogSync(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/plancatalogsync\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.PlanCatalogSyncRequest()\ntry:\n result = client.admin.plan_catalog_sync(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.planCatalogSync(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/sync:plan\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{}'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/catalog/sync:plan","slug":"plan-catalog-sync"}
Apply catalog sync
Changed in v0.8.0 (new features): The model catalog can be synced through the admin API: preview what a sync would change, apply it in the background pinned to the exact documents previewed, and poll the run's progress. One sync runs at a time.
What it does: Starts one background sync run and returns it RUNNING; poll GetCatalogSyncRun for progress. At most one run exists at a time -- a second apply while one is in flight fails with ALREADY_EXISTS. The request MUST carry the sources (with sha256 digests) the preview reported. The apply re-fetches pinned to those digests, so what gets applied is byte-for-byte what the human reviewed; a published catalogue that changed in between fails the run with an instruction to re-preview rather than silently applying something nobody looked at. Error-code contract, which a dashboard branches on (never on message text): - ABORTED: the preview went stale -- the source configuration changed under the reviewed pin set. Re-run PlanCatalogSync and apply again. The same verdict reached asynchronously (the published catalogue changed between preview and apply) surfaces as a FAILED run with failure_reason = STALE_CATALOG. - FAILED_PRECONDITION: the plane cannot sync until an operator fixes something (sources unconfigured, published catalogue malformed). Retrying as-is will not help. - ALREADY_EXISTS: a run is in flight; poll it. - INVALID_ARGUMENT: the request is missing the preview's sources. All-or-nothing by design: no per-entry selection, and no disable-absent. The published catalogue is a curated SUBSET of what a plane may legitimately hold (vertex and vertexanthropic models are seeded but not published), so a one-click disable-absent would silently turn off models customers are routing to. The plan lists absent models read-only instead.
Request fields:
| Field | Required | Description |
|---|---|---|
expected_catalog_version | no | The preview's catalog_version, verbatim (may be empty, as the envelope field is optional). A cheap first check before the digest comparison. |
expected_sources | no | The preview's sources, REQUIRED, matched against the configured source set by display name. Each sha256 pins the apply's re-fetch of that document; any mismatch fails the run before anything is written. |
Response fields:
| Field | Required | Description |
|---|---|---|
run | no | The run just started, phase RUNNING. Poll GetCatalogSyncRun. |
{"signatures":{"go":"func (x *AdminClient) ApplyCatalogSync(ctx context.Context, req *adminv1.ApplyCatalogSyncRequest) (*adminv1.ApplyCatalogSyncResponse, error)","python":"apply_catalog_sync(req: admin_pb2.ApplyCatalogSyncRequest) -\u003e ApplyCatalogSyncResponse","typescript":"applyCatalogSync(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ApplyCatalogSyncRequestSchema\u003e): Promise\u003cApplyCatalogSyncResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/sync:apply\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"expected_catalog_version\": \"...\",\n \"expected_sources\": []\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ApplyCatalogSyncRequest{}\n\n\tresp, err := client.Admin().ApplyCatalogSync(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/applycatalogsync\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ApplyCatalogSyncRequest()\ntry:\n result = client.admin.apply_catalog_sync(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.applyCatalogSync(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/sync:apply\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"expected_catalog_version\": \"...\",\n \"expected_sources\": []\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/catalog/sync:apply","slug":"apply-catalog-sync"}
Get catalog sync run
Changed in v0.8.0 (new features): The model catalog can be synced through the admin API: preview what a sync would change, apply it in the background pinned to the exact documents previewed, and poll the run's progress. One sync runs at a time.
What it does: Returns the most recent apply run, running or finished. An unset run means no apply has ever been started on this plane.
Request body: None.
Response fields:
| Field | Required | Description |
|---|---|---|
run | no | Unset when no apply has ever been started on this plane. |
{"signatures":{"go":"func (x *AdminClient) GetCatalogSyncRun(ctx context.Context, req *adminv1.GetCatalogSyncRunRequest) (*adminv1.GetCatalogSyncRunResponse, error)","python":"get_catalog_sync_run(req: admin_pb2.GetCatalogSyncRunRequest) -\u003e GetCatalogSyncRunResponse","typescript":"getCatalogSyncRun(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetCatalogSyncRunRequestSchema\u003e): Promise\u003cGetCatalogSyncRunResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/sync/run\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetCatalogSyncRunRequest{}\n\n\tresp, err := client.Admin().GetCatalogSyncRun(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getcatalogsyncrun\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetCatalogSyncRunRequest()\ntry:\n result = client.admin.get_catalog_sync_run(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getCatalogSyncRun(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/catalog/sync/run\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/catalog/sync/run","slug":"get-catalog-sync-run"}
Get model lifecycles
Changed in v0.8.0 (new features): Admins can read whether a model in the catalog is retired, deprecated, new or in preview, with the reason and any retirement date. A model the catalog does not contain is left out of the result.
What it does: Lifecycle verdicts (retired / deprecated / new / preview) for a batch of catalogue models, keyed by model id (fraser#10228). The verdict is computed by catalogsync.LifecycleOfModel -- the function the catalog sync itself acts on -- so a consumer badges a model with the same answer the sync reached, rather than re-deriving it from metadata and drifting. Batch-by-id rather than a field on Model because the Admin Console lists models from its own ai_models query, not from this service: it already holds the ids and needs only the verdicts. An id that matches no catalogue row is ABSENT from the response map, never present with a zero verdict: a zero verdict means "no lifecycle signal" and would render as a normal live model. Disabled models are included -- a retired model is usually disabled, and that is exactly the one to badge.
Request fields:
| Field | Required | Description |
|---|---|---|
model_ids | no | Catalogue model ids (ai_models.id). Duplicates are allowed and collapse to one map entry. Empty returns an empty map. max_items 1000: the whole current catalogue (~700 models) fits in one call with headroom, so the Console never has to batch a full listing, while staying well under the catalogue store's 5000-row page cap, so one request is always answered by one bounded read. |
Response fields:
| Field | Required | Description |
|---|---|---|
lifecycles | no | Verdict per requested model id that exists in the catalogue. Ids with no catalogue row are absent, not zero-valued -- see GetModelLifecycles. |
{"signatures":{"go":"func (x *AdminClient) GetModelLifecycles(ctx context.Context, req *adminv1.GetModelLifecyclesRequest) (*adminv1.GetModelLifecyclesResponse, error)","python":"get_model_lifecycles(req: admin_pb2.GetModelLifecyclesRequest) -\u003e GetModelLifecyclesResponse","typescript":"getModelLifecycles(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetModelLifecyclesRequestSchema\u003e): Promise\u003cGetModelLifecyclesResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/catalog:model-lifecycles\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"model_ids\": []\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetModelLifecyclesRequest{}\n\n\tresp, err := client.Admin().GetModelLifecycles(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getmodellifecycles\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetModelLifecyclesRequest()\ntry:\n result = client.admin.get_model_lifecycles(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getModelLifecycles(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/catalog:model-lifecycles\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"model_ids\": []\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/catalog:model-lifecycles","slug":"get-model-lifecycles"}
Add project model
Changed in v0.8.0 (bug fixes): Adding or removing a model from a project now updates keys that carry their own settings (BYOK, fallback, traffic split, or a rate limit), so they no longer keep routing against the old model list. A key created with CreateApiKey or IssueMyKey now gets its own routes instead of waiting on an unrelated change. Both updates are sent in the background, so the call returns without waiting for them.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to assign the model to. |
model_id | no | Catalog model UUID to assign. |
Response fields:
| Field | Required | Description |
|---|---|---|
entry | no | The created model assignment. |
{"signatures":{"go":"func (x *AdminClient) AddProjectModel(ctx context.Context, req *adminv1.AddProjectModelRequest) (*adminv1.AddProjectModelResponse, error)","python":"add_project_model(req: admin_pb2.AddProjectModelRequest) -\u003e AddProjectModelResponse","typescript":"addProjectModel(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.AddProjectModelRequestSchema\u003e): Promise\u003cAddProjectModelResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"model_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.AddProjectModelRequest{}\n\n\tresp, err := client.Admin().AddProjectModel(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/addprojectmodel\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.AddProjectModelRequest()\ntry:\n result = client.admin.add_project_model(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.addProjectModel(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"model_id\": \"...\"\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/models","slug":"add-project-model"}
List project models
no scope on catalog side; assign/unassign require project_owner
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project whose assigned models to list. |
Response fields:
| Field | Required | Description |
|---|---|---|
entries | no | Models assigned to the project. |
{"signatures":{"go":"func (x *AdminClient) ListProjectModels(ctx context.Context, req *adminv1.ListProjectModelsRequest) (*adminv1.ListProjectModelsResponse, error)","python":"list_project_models(req: admin_pb2.ListProjectModelsRequest) -\u003e ListProjectModelsResponse","typescript":"listProjectModels(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectModelsRequestSchema\u003e): Promise\u003cListProjectModelsResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectModelsRequest{}\n\n\tresp, err := client.Admin().ListProjectModels(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojectmodels\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectModelsRequest()\ntry:\n result = client.admin.list_project_models(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjectModels(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../models\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/models","slug":"list-project-models"}
Remove project model
Changed in v0.8.0 (bug fixes): Adding or removing a model from a project now updates keys that carry their own settings (BYOK, fallback, traffic split, or a rate limit), so they no longer keep routing against the old model list. A key created with CreateApiKey or IssueMyKey now gets its own routes instead of waiting on an unrelated change. Both updates are sent in the background, so the call returns without waiting for them.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to remove the model from. |
model_id | no | Catalog model UUID to unassign. |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the assignment was removed. |
{"signatures":{"go":"func (x *AdminClient) RemoveProjectModel(ctx context.Context, req *adminv1.RemoveProjectModelRequest) (*adminv1.RemoveProjectModelResponse, error)","python":"remove_project_model(req: admin_pb2.RemoveProjectModelRequest) -\u003e RemoveProjectModelResponse","typescript":"removeProjectModel(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.RemoveProjectModelRequestSchema\u003e): Promise\u003cRemoveProjectModelResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../models/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.RemoveProjectModelRequest{}\n\n\tresp, err := client.Admin().RemoveProjectModel(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/removeprojectmodel\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.RemoveProjectModelRequest()\ntry:\n result = client.admin.remove_project_model(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.removeProjectModel(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../models/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/models/{model_id}","slug":"remove-project-model"}
Add project provider
Changed in v0.11.0 (bug fixes): A request with a NUL character in a name, description or filter field now returns 400 invalid_argument. It returned 500 internal before, which clients retry and which counted as a server failure. This applies when the management plane uses the extended query protocol, which is the default. A deployment that sets global.useSimpleProtocol (USE_QUERY_EXEC_MODE_SIMPLE_PROTOCOL=true, used with pgbouncer) still returns 500 for these requests.
Changed in v0.9.0 (behaviour changes): Adding or removing a provider on a project's allow-list through the API now needs the project provider permission, which Project Owner and Super Admin hold, as the Admin Console already did. Provider Admin and Model Admin no longer give it, and neither does a custom role with only the providers permissions.
Changed in v0.9.0 (new features): Project admins can add and remove the providers on their own project's allow-list.
What it does: Adds a provider to the project's allow-list. A project admin may call it for their own project.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to enable the provider for. |
provider_name | no | Provider name to enable (e.g. "openai"). |
Response fields:
| Field | Required | Description |
|---|---|---|
entry | no | The created provider assignment. |
{"signatures":{"go":"func (x *AdminClient) AddProjectProvider(ctx context.Context, req *adminv1.AddProjectProviderRequest) (*adminv1.AddProjectProviderResponse, error)","python":"add_project_provider(req: admin_pb2.AddProjectProviderRequest) -\u003e AddProjectProviderResponse","typescript":"addProjectProvider(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.AddProjectProviderRequestSchema\u003e): Promise\u003cAddProjectProviderResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../providers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"provider_name\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.AddProjectProviderRequest{}\n\n\tresp, err := client.Admin().AddProjectProvider(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/addprojectprovider\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.AddProjectProviderRequest()\ntry:\n result = client.admin.add_project_provider(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.addProjectProvider(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../providers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"provider_name\": \"...\"\n }'"},"persona":"App Developer (API key)","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/providers","slug":"add-project-provider"}
List project providers
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project whose enabled providers to list. |
Response fields:
| Field | Required | Description |
|---|---|---|
entries | no | Providers enabled for the project. |
{"signatures":{"go":"func (x *AdminClient) ListProjectProviders(ctx context.Context, req *adminv1.ListProjectProvidersRequest) (*adminv1.ListProjectProvidersResponse, error)","python":"list_project_providers(req: admin_pb2.ListProjectProvidersRequest) -\u003e ListProjectProvidersResponse","typescript":"listProjectProviders(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectProvidersRequestSchema\u003e): Promise\u003cListProjectProvidersResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../providers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectProvidersRequest{}\n\n\tresp, err := client.Admin().ListProjectProviders(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojectproviders\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectProvidersRequest()\ntry:\n result = client.admin.list_project_providers(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjectProviders(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../providers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/providers","slug":"list-project-providers"}
Remove project provider
Changed in v0.9.0 (behaviour changes): Removing a provider from a project's allow-list fails with FAILED_PRECONDITION while the project still has models from that provider.
Changed in v0.9.0 (behaviour changes): Adding or removing a provider on a project's allow-list through the API now needs the project provider permission, which Project Owner and Super Admin hold, as the Admin Console already did. Provider Admin and Model Admin no longer give it, and neither does a custom role with only the providers permissions.
Changed in v0.9.0 (new features): Project admins can add and remove the providers on their own project's allow-list.
What it does: Removes a provider from the project's allow-list. Fails FAILED_PRECONDITION while the project still has models from that provider: unassign them first. A project admin may call it for their own project.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to disable the provider for. |
provider_name | no | Provider name to disable. |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the provider was removed. |
{"signatures":{"go":"func (x *AdminClient) RemoveProjectProvider(ctx context.Context, req *adminv1.RemoveProjectProviderRequest) (*adminv1.RemoveProjectProviderResponse, error)","python":"remove_project_provider(req: admin_pb2.RemoveProjectProviderRequest) -\u003e RemoveProjectProviderResponse","typescript":"removeProjectProvider(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.RemoveProjectProviderRequestSchema\u003e): Promise\u003cRemoveProjectProviderResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../providers/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.RemoveProjectProviderRequest{}\n\n\tresp, err := client.Admin().RemoveProjectProvider(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/removeprojectprovider\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.RemoveProjectProviderRequest()\ntry:\n result = client.admin.remove_project_provider(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.removeProjectProvider(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../providers/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"App Developer (API key)","httpVerb":"DELETE","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/providers/{provider_name}","slug":"remove-project-provider"}
Add project mcp server
Changed in v0.8.0 (behaviour changes): Listing, adding and removing a project's MCP servers now needs the project MCP permission. The MCP Admin role doesn't include it, so its holders need Project Owner or Super Admin for all three.
Changed in v0.8.0 (new features): Project owners can add and remove their project's MCP servers, and Viewers can list them. The list shows each server's name, description, icon, enabled state and last update, including servers disabled since, and can be paged, searched by name, filtered by enabled state and sorted.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to assign the MCP server to. |
server_id | no | Catalog server ID to assign (e.g. "github"). |
Response fields:
| Field | Required | Description |
|---|---|---|
entry | no | The created MCP server assignment. |
{"signatures":{"go":"func (x *AdminClient) AddProjectMcpServer(ctx context.Context, req *adminv1.AddProjectMcpServerRequest) (*adminv1.AddProjectMcpServerResponse, error)","python":"add_project_mcp_server(req: admin_pb2.AddProjectMcpServerRequest) -\u003e AddProjectMcpServerResponse","typescript":"addProjectMcpServer(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.AddProjectMcpServerRequestSchema\u003e): Promise\u003cAddProjectMcpServerResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../mcp-servers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"server_id\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.AddProjectMcpServerRequest{}\n\n\tresp, err := client.Admin().AddProjectMcpServer(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/addprojectmcpserver\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.AddProjectMcpServerRequest()\ntry:\n result = client.admin.add_project_mcp_server(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.addProjectMcpServer(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../mcp-servers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"server_id\": \"...\"\n }'"},"persona":"App Developer (API key)","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/mcp-servers","slug":"add-project-mcp-server"}
List project mcp servers
Changed in v0.11.0 (bug fixes): A request with a NUL character in a name, description or filter field now returns 400 invalid_argument. It returned 500 internal before, which clients retry and which counted as a server failure. This applies when the management plane uses the extended query protocol, which is the default. A deployment that sets global.useSimpleProtocol (USE_QUERY_EXEC_MODE_SIMPLE_PROTOCOL=true, used with pgbouncer) still returns 500 for these requests.
Changed in v0.8.0 (behaviour changes): Listing, adding and removing a project's MCP servers now needs the project MCP permission. The MCP Admin role doesn't include it, so its holders need Project Owner or Super Admin for all three.
Changed in v0.8.0 (new features): Project owners can add and remove their project's MCP servers, and Viewers can list them. The list shows each server's name, description, icon, enabled state and last update, including servers disabled since, and can be paged, searched by name, filtered by enabled state and sorted.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project whose assigned MCP servers to list. |
page | no | Paging and order. order_by is one of server_id, name, updated_at or is_enabled, optionally followed by asc or desc; empty orders by server ID. Unset returns every server. |
search | no | Case-insensitive substring match on the server name; empty matches all. |
enabled | no | When set, only servers whose catalog entry has this enabled state. |
Response fields:
| Field | Required | Description |
|---|---|---|
entries | no | MCP servers assigned to the project. |
page | no | Next page cursor; unset when the request was unpaged or this is the last page. |
total | no | Servers matching search and enabled, across all pages. |
{"signatures":{"go":"func (x *AdminClient) ListProjectMcpServers(ctx context.Context, req *adminv1.ListProjectMcpServersRequest) (*adminv1.ListProjectMcpServersResponse, error)","python":"list_project_mcp_servers(req: admin_pb2.ListProjectMcpServersRequest) -\u003e ListProjectMcpServersResponse","typescript":"listProjectMcpServers(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectMcpServersRequestSchema\u003e): Promise\u003cListProjectMcpServersResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../mcp-servers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectMcpServersRequest{}\n\n\tresp, err := client.Admin().ListProjectMcpServers(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojectmcpservers\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectMcpServersRequest()\ntry:\n result = client.admin.list_project_mcp_servers(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjectMcpServers(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../mcp-servers\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"App Developer (API key)","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/mcp-servers","slug":"list-project-mcp-servers"}
Remove project mcp server
Changed in v0.10.0 (security updates): Removing a catalog MCP server from a project now also detaches it from the legacy MCP profiles of users in the project, and editing the tools of a server that the project no longer grants is refused with PERMISSION_DENIED. Before, a legacy profile kept serving a server after its grant was removed.
Changed in v0.8.0 (behaviour changes): Listing, adding and removing a project's MCP servers now needs the project MCP permission. The MCP Admin role doesn't include it, so its holders need Project Owner or Super Admin for all three.
Changed in v0.8.0 (new features): Project owners can add and remove their project's MCP servers, and Viewers can list them. The list shows each server's name, description, icon, enabled state and last update, including servers disabled since, and can be paged, searched by name, filtered by enabled state and sorted.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to remove the MCP server from. |
server_id | no | Catalog server ID to remove. |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the MCP server assignment was removed. |
{"signatures":{"go":"func (x *AdminClient) RemoveProjectMcpServer(ctx context.Context, req *adminv1.RemoveProjectMcpServerRequest) (*adminv1.RemoveProjectMcpServerResponse, error)","python":"remove_project_mcp_server(req: admin_pb2.RemoveProjectMcpServerRequest) -\u003e RemoveProjectMcpServerResponse","typescript":"removeProjectMcpServer(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.RemoveProjectMcpServerRequestSchema\u003e): Promise\u003cRemoveProjectMcpServerResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../mcp-servers/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.RemoveProjectMcpServerRequest{}\n\n\tresp, err := client.Admin().RemoveProjectMcpServer(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/removeprojectmcpserver\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.RemoveProjectMcpServerRequest()\ntry:\n result = client.admin.remove_project_mcp_server(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.removeProjectMcpServer(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../mcp-servers/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"App Developer (API key)","httpVerb":"DELETE","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/mcp-servers/{server_id}","slug":"remove-project-mcp-server"}
List project mcp server candidates
Changed in v0.8.0 (new features): Project owners can list the enabled MCP servers their project doesn't have yet, searched by name and paged, to pick which ones to add.
What it does: Returns enabled catalog servers not yet assigned to the project, ordered by name, for the add-server picker.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project the candidates are for. |
search | no | Case-insensitive substring match on the server name; empty matches all. |
page_size | no | Max servers per page (0 = server default of 50). |
page_token | no | Opaque cursor from a previous response's next_page_token. |
Response fields:
| Field | Required | Description |
|---|---|---|
candidates | no | Page of candidates, ordered by name then id. |
next_page_token | no | Cursor for the next page; empty when there are no more results. |
{"signatures":{"go":"func (x *AdminClient) ListProjectMcpServerCandidates(ctx context.Context, req *adminv1.ListProjectMcpServerCandidatesRequest) (*adminv1.ListProjectMcpServerCandidatesResponse, error)","python":"list_project_mcp_server_candidates(req: admin_pb2.ListProjectMcpServerCandidatesRequest) -\u003e ListProjectMcpServerCandidatesResponse","typescript":"listProjectMcpServerCandidates(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectMcpServerCandidatesRequestSchema\u003e): Promise\u003cListProjectMcpServerCandidatesResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../mcp-server-candidates\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectMcpServerCandidatesRequest{}\n\n\tresp, err := client.Admin().ListProjectMcpServerCandidates(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojectmcpservercandidates\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectMcpServerCandidatesRequest()\ntry:\n result = client.admin.list_project_mcp_server_candidates(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjectMcpServerCandidates(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../mcp-server-candidates\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"App Developer (API key)","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/mcp-server-candidates","slug":"list-project-mcp-server-candidates"}
Trigger project mcp
What it does: (re)materializes the per-Project-Gateway MCP config for every gateway the (customer_id, project_id) is attached to. The dashboard MCP profile mutation path calls this after a profile create/update/delete so a freshly-created profile enters its project gateways' MCP_PROFILE config; without it the per-gateway config-gen never re-runs and /mcp/<profile> 404s on a strict-isolation gateway DP. Best-effort + dormant when the project has no gateways.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project whose gateways' MCP config to refresh. |
{"signatures":{"go":"func (x *AdminClient) TriggerProjectMcp(ctx context.Context, req *adminv1.TriggerProjectMcpRequest) (*adminv1.TriggerProjectMcpResponse, error)","python":"trigger_project_mcp(req: admin_pb2.TriggerProjectMcpRequest) -\u003e TriggerProjectMcpResponse","typescript":"triggerProjectMcp(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.TriggerProjectMcpRequestSchema\u003e): Promise\u003cTriggerProjectMcpResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../mcp:trigger\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{}'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.TriggerProjectMcpRequest{}\n\n\tresp, err := client.Admin().TriggerProjectMcp(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/triggerprojectmcp\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.TriggerProjectMcpRequest()\ntry:\n result = client.admin.trigger_project_mcp(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.triggerProjectMcp(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../mcp:trigger\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{}'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/mcp:trigger","slug":"trigger-project-mcp"}
Get project settings
Changed in v0.8.0 (bug fixes): Getting, setting or deleting a project setting now returns NOT_FOUND when the project is missing or deleted. Deleting a project now deletes its settings, so a new project with the same name starts with none. The default project is still created on demand.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project whose settings to fetch. |
Response fields:
| Field | Required | Description |
|---|---|---|
settings | no | All settings for the project. |
{"signatures":{"go":"func (x *AdminClient) GetProjectSettings(ctx context.Context, req *adminv1.GetProjectSettingsRequest) (*adminv1.GetProjectSettingsResponse, error)","python":"get_project_settings(req: admin_pb2.GetProjectSettingsRequest) -\u003e GetProjectSettingsResponse","typescript":"getProjectSettings(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetProjectSettingsRequestSchema\u003e): Promise\u003cGetProjectSettingsResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../settings\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetProjectSettingsRequest{}\n\n\tresp, err := client.Admin().GetProjectSettings(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getprojectsettings\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetProjectSettingsRequest()\ntry:\n result = client.admin.get_project_settings(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getProjectSettings(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../settings\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/settings","slug":"get-project-settings"}
Upsert project setting
Changed in v0.8.0 (bug fixes): Getting, setting or deleting a project setting now returns NOT_FOUND when the project is missing or deleted. Deleting a project now deletes its settings, so a new project with the same name starts with none. The default project is still created on demand.
Changed in v0.8.0 (bug fixes): Project default settings, project membership changes, the request-log mode, and rate-limit policies moved to another target now reach your gateways within the usual update cycle. They were previously saved but not pushed, so keys kept an old rate limit or fallback, a removed member kept the project's shared provider keys, and a moved policy kept limiting its old keys. A project-wide rate limit is also now enforced on keys with no settings of their own.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to set the value on. |
setting_name | no | Setting key to create or update ("global-fallback" or "rate-limit"). |
setting_value | no | New string-encoded value for the setting. |
Response fields:
| Field | Required | Description |
|---|---|---|
setting | no | The created or updated setting. |
{"signatures":{"go":"func (x *AdminClient) UpsertProjectSetting(ctx context.Context, req *adminv1.UpsertProjectSettingRequest) (*adminv1.UpsertProjectSettingResponse, error)","python":"upsert_project_setting(req: admin_pb2.UpsertProjectSettingRequest) -\u003e UpsertProjectSettingResponse","typescript":"upsertProjectSetting(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpsertProjectSettingRequestSchema\u003e): Promise\u003cUpsertProjectSettingResponse\u003e","curl":"curl -X PUT \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../settings/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"setting_value\": \"...\"\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpsertProjectSettingRequest{}\n\n\tresp, err := client.Admin().UpsertProjectSetting(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/upsertprojectsetting\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpsertProjectSettingRequest()\ntry:\n result = client.admin.upsert_project_setting(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.upsertProjectSetting(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PUT \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../settings/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"setting_value\": \"...\"\n }'"},"persona":"Admin","httpVerb":"PUT","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/settings/{setting_name}","slug":"upsert-project-setting"}
Delete project setting
Changed in v0.8.0 (bug fixes): Getting, setting or deleting a project setting now returns NOT_FOUND when the project is missing or deleted. Deleting a project now deletes its settings, so a new project with the same name starts with none. The default project is still created on demand.
Changed in v0.8.0 (bug fixes): Project default settings, project membership changes, the request-log mode, and rate-limit policies moved to another target now reach your gateways within the usual update cycle. They were previously saved but not pushed, so keys kept an old rate limit or fallback, a removed member kept the project's shared provider keys, and a moved policy kept limiting its old keys. A project-wide rate limit is also now enforced on keys with no settings of their own.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to delete the setting from. |
setting_name | no | Setting key to delete ("global-fallback" or "rate-limit"). |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True if the setting was deleted. |
{"signatures":{"go":"func (x *AdminClient) DeleteProjectSetting(ctx context.Context, req *adminv1.DeleteProjectSettingRequest) (*adminv1.DeleteProjectSettingResponse, error)","python":"delete_project_setting(req: admin_pb2.DeleteProjectSettingRequest) -\u003e DeleteProjectSettingResponse","typescript":"deleteProjectSetting(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.DeleteProjectSettingRequestSchema\u003e): Promise\u003cDeleteProjectSettingResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../settings/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.DeleteProjectSettingRequest{}\n\n\tresp, err := client.Admin().DeleteProjectSetting(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/deleteprojectsetting\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.DeleteProjectSettingRequest()\ntry:\n result = client.admin.delete_project_setting(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.deleteProjectSetting(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../settings/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/settings/{setting_name}","slug":"delete-project-setting"}
Get project OIDC config
Changed in v0.10.0 (new features): A project's OIDC contract now names the token claim that identifies one caller, identity_claim, which is sub unless you name another, and how many callers the project may hold, principal_cap, which is 100 unless you set one at least 1. On a 0.10.0 data plane each caller gets its own API key, so budgets and rate limits apply per caller. The cap is enforced when a data plane resolves a contract caller. Existing contracts get both defaults. Omitting either field on a write keeps the stored value.
Changed in v0.7.0 (new features): A project can now publish an OIDC contract, naming the issuer that mints its tokens, the audience and scope they must carry and an optional entitlement. The issuer's discovery document is read as you write it, so an unreachable issuer is refused then. A contract naming an issuer and audience another organization's project already names is refused. A data plane on 0.7.0 or later admits callers against the contract; one below it answers them with a 401.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project whose OIDC contract to fetch. |
Response fields:
| Field | Required | Description |
|---|---|---|
config | no | The project's contract. Absent when the project has none, which is the state every project starts in and the state in which it admits no OIDC caller. |
{"signatures":{"go":"func (x *AdminClient) GetProjectOIDCConfig(ctx context.Context, req *adminv1.GetProjectOIDCConfigRequest) (*adminv1.GetProjectOIDCConfigResponse, error)","python":"get_project_oidc_config(req: admin_pb2.GetProjectOIDCConfigRequest) -\u003e GetProjectOIDCConfigResponse","typescript":"getProjectOIDCConfig(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetProjectOIDCConfigRequestSchema\u003e): Promise\u003cGetProjectOIDCConfigResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../oidc\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetProjectOIDCConfigRequest{}\n\n\tresp, err := client.Admin().GetProjectOIDCConfig(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getprojectoidcconfig\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetProjectOIDCConfigRequest()\ntry:\n result = client.admin.get_project_oidc_config(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getProjectOIDCConfig(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../oidc\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/oidc","slug":"get-project-oidc-config"}
Upsert project OIDC config
Changed in v0.11.0 (security updates): A disabled project OIDC contract no longer reserves its issuer and audience, so another organization can enable a contract for that pair. Enabling a contract is still refused while another organization's enabled contract names the same issuer and audience, and the refusal now tells you to ask a platform administrator to release the pair. The refusal's audit entry names the holding organization and project, and the delete audit entry records the issuer and audience it released.
Changed in v0.11.0 (bug fixes): Changes that check a data plane's version, such as provider overrides, shared and catch-all hostnames, OIDC contracts and the newer rate-limit dimensions, no longer refuse a data plane on 0.11.0 or newer that was just upgraded or has had no configuration change for a day, because it now reports its version on every poll. A data plane silent for 24 hours is refused as down, disconnected or older than 0.11.0, with a prompt to check its connection and build.
Changed in v0.10.0 (behaviour changes): Writing a project's OIDC contract is refused on Agent Router Service (SaaS). Enabling a contract is refused while a data plane serving the project runs a build older than 0.10.0 or has not reported its build, and so is attaching a project whose contract is enabled to such a data plane. Each refusal names the data plane.
Changed in v0.10.0 (new features): A project's OIDC contract now names the token claim that identifies one caller, identity_claim, which is sub unless you name another, and how many callers the project may hold, principal_cap, which is 100 unless you set one at least 1. On a 0.10.0 data plane each caller gets its own API key, so budgets and rate limits apply per caller. The cap is enforced when a data plane resolves a contract caller. Existing contracts get both defaults. Omitting either field on a write keeps the stored value.
Changed in v0.7.0 (new features): A project can now publish an OIDC contract, naming the issuer that mints its tokens, the audience and scope they must carry and an optional entitlement. The issuer's discovery document is read as you write it, so an unreachable issuer is refused then. A contract naming an issuer and audience another organization's project already names is refused. A data plane on 0.7.0 or later admits callers against the contract; one below it answers them with a 401.
Changed in v0.7.0 (new features): The management plane refuses to fetch an OIDC issuer's discovery document from a non-public address: loopback, link-local, private, carrier-grade NAT, unique-local, unspecified, or another range reserved from public routing, such as benchmarking. It checks the address it connects to, redirects included, and the refusal names the setting that lifts it. A redirect is followed only to https on the issuer's own host and port.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to write the contract on. |
issuer | no | The identity provider that mints tokens for this project, e.g. "https://login.acmebank.com". Must be an absolute https URL, and the management plane fetches its discovery document to resolve the JWKS URI, so an issuer it cannot reach is refused here rather than at a caller's request. |
audience | no | The audience the token must carry, in practice the client ID of the customer's own application registration. |
required_scope | no | The scope the token must carry, e.g. "ai.payments.use". One scope, so it carries no space. |
required_entitlement | no | The entitlement the token must carry, e.g. the group the identity belongs to. Empty means the project requires none. |
enabled | no | Whether the data plane admits OIDC callers to this project. Write false to refuse every OIDC caller while keeping the rest of the contract. |
identity_claim | no | The token claim whose value identifies one caller. Omit it to keep the stored value, or "sub" on a new contract. Pick a claim the identity provider never reassigns: sub, or a client ID for a machine client. A mutable claim such as email hands one caller's key to whoever receives the value next. |
principal_cap | no | How many callers the project may hold. Omit it to keep the stored value, or 100 on a new contract. The value is at least 1, with no upper bound. |
Response fields:
| Field | Required | Description |
|---|---|---|
config | no | The stored contract, carrying the JWKS URI the management plane resolved. |
{"signatures":{"go":"func (x *AdminClient) UpsertProjectOIDCConfig(ctx context.Context, req *adminv1.UpsertProjectOIDCConfigRequest) (*adminv1.UpsertProjectOIDCConfigResponse, error)","python":"upsert_project_oidc_config(req: admin_pb2.UpsertProjectOIDCConfigRequest) -\u003e UpsertProjectOIDCConfigResponse","typescript":"upsertProjectOIDCConfig(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpsertProjectOIDCConfigRequestSchema\u003e): Promise\u003cUpsertProjectOIDCConfigResponse\u003e","curl":"curl -X PUT \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../oidc\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"issuer\": \"...\",\n \"audience\": \"...\",\n \"required_scope\": \"...\",\n \"required_entitlement\": \"...\",\n \"enabled\": false,\n \"identity_claim\": \"...\",\n \"principal_cap\": 0\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpsertProjectOIDCConfigRequest{}\n\n\tresp, err := client.Admin().UpsertProjectOIDCConfig(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/upsertprojectoidcconfig\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpsertProjectOIDCConfigRequest()\ntry:\n result = client.admin.upsert_project_oidc_config(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.upsertProjectOIDCConfig(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PUT \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../oidc\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"issuer\": \"...\",\n \"audience\": \"...\",\n \"required_scope\": \"...\",\n \"required_entitlement\": \"...\",\n \"enabled\": false,\n \"identity_claim\": \"...\",\n \"principal_cap\": 0\n }'"},"persona":"Admin","httpVerb":"PUT","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/oidc","slug":"upsert-project-oidc-config"}
Delete project OIDC config
Changed in v0.7.0 (new features): A project can now publish an OIDC contract, naming the issuer that mints its tokens, the audience and scope they must carry and an optional entitlement. The issuer's discovery document is read as you write it, so an unreachable issuer is refused then. A contract naming an issuer and audience another organization's project already names is refused. A data plane on 0.7.0 or later admits callers against the contract; one below it answers them with a 401.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Owning customer slug. |
project_id | no | Project to remove the contract from, which stops it admitting OIDC callers. |
Response fields:
| Field | Required | Description |
|---|---|---|
success | no | True when the project no longer carries a contract, including when it carried none to begin with. |
{"signatures":{"go":"func (x *AdminClient) DeleteProjectOIDCConfig(ctx context.Context, req *adminv1.DeleteProjectOIDCConfigRequest) (*adminv1.DeleteProjectOIDCConfigResponse, error)","python":"delete_project_oidc_config(req: admin_pb2.DeleteProjectOIDCConfigRequest) -\u003e DeleteProjectOIDCConfigResponse","typescript":"deleteProjectOIDCConfig(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.DeleteProjectOIDCConfigRequestSchema\u003e): Promise\u003cDeleteProjectOIDCConfigResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../oidc\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.DeleteProjectOIDCConfigRequest{}\n\n\tresp, err := client.Admin().DeleteProjectOIDCConfig(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/deleteprojectoidcconfig\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.DeleteProjectOIDCConfigRequest()\ntry:\n result = client.admin.delete_project_oidc_config(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.deleteProjectOIDCConfig(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../projects/proj_01H.../oidc\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/admin/v1/customers/{customer_id}/projects/{project_id}/oidc","slug":"delete-project-oidc-config"}
Get system setting
Changed in v0.9.0 (new features): GetSystemSetting takes an optional include_config_event flag for guardrails.enabled. It returns the status of the latest push of that setting to your data planes in the last 24 hours.
Changed in v0.1.5 (bug fixes): Reading and writing a system setting whose key contains a colon (for example dataplane-url:<workspace_id>) now works over REST. GET and PUT /admin/v1/system-settings/{key} previously returned an empty 200 response for such keys; both the raw and the percent-encoded forms of the key now resolve.
Request fields:
| Field | Required | Description |
|---|---|---|
key | no | Deployment-global system_settings key to read (e.g. "setup-completed"). |
include_config_event | no | When true, the response also carries config_event: the latest configuration push of the last 24 hours for this setting, so a caller can show whether a change has reached the data planes. Only a push that a change to this setting caused counts; a push for a guardrail, rule or other setting change does not. Supported only for "guardrails.enabled"; any other key returns INVALID_ARGUMENT. Unset or false, the response is unchanged. |
Response fields:
| Field | Required | Description |
|---|---|---|
value | no | The stored value; empty when the key is absent (see found). |
found | no | True when the key exists with a non-empty value. UpsertSystemSetting rejects empty values (value has min_len: 1), so a stored key always has a non-empty value and this never diverges from raw key existence. |
config_event | no | The latest configuration push for this setting in the last 24 hours. Set only when include_config_event was true and such a push exists. |
{"signatures":{"go":"func (x *AdminClient) GetSystemSetting(ctx context.Context, req *adminv1.GetSystemSettingRequest) (*adminv1.GetSystemSettingResponse, error)","python":"get_system_setting(req: admin_pb2.GetSystemSettingRequest) -\u003e GetSystemSettingResponse","typescript":"getSystemSetting(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.GetSystemSettingRequestSchema\u003e): Promise\u003cGetSystemSettingResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/system-settings/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.GetSystemSettingRequest{}\n\n\tresp, err := client.Admin().GetSystemSetting(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/getsystemsetting\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.GetSystemSettingRequest()\ntry:\n result = client.admin.get_system_setting(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.getSystemSetting(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/system-settings/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/system-settings/{key}","slug":"get-system-setting"}
Upsert system setting
Changed in v0.11.0 (new features): An admin can now change two management plane address checks without restarting valet. The system settings oidc.discovery_allow_private_addresses and gateway_auth.jwks_allow_private_addresses override OIDC_DISCOVERY_ALLOW_PRIVATE_ADDRESSES and GATEWAY_AUTH_JWKS_ALLOW_PRIVATE_ADDRESSES. Each takes true, false or inherit, and UpsertSystemSetting refuses any other value for them.
Changed in v0.8.0 (bug fixes): Project default settings, project membership changes, the request-log mode, and rate-limit policies moved to another target now reach your gateways within the usual update cycle. They were previously saved but not pushed, so keys kept an old rate limit or fallback, a removed member kept the project's shared provider keys, and a moved policy kept limiting its old keys. A project-wide rate limit is also now enforced on keys with no settings of their own.
Changed in v0.1.5 (bug fixes): Reading and writing a system setting whose key contains a colon (for example dataplane-url:<workspace_id>) now works over REST. GET and PUT /admin/v1/system-settings/{key} previously returned an empty 200 response for such keys; both the raw and the percent-encoded forms of the key now resolve.
Request fields:
| Field | Required | Description |
|---|---|---|
key | no | Deployment-global system_settings key to write (e.g. "deployment-mode"). |
value | no | Value to store under key. Must be non-empty: an empty write would read back as not-found (GetSystemSettingResponse.found is value != ""), so it is rejected rather than silently creating an invisible row. |
if_absent | no | When true, only insert if the key is absent (atomic ON CONFLICT DO NOTHING); an existing value is left untouched. When false, upsert (create or replace). |
Response fields:
| Field | Required | Description |
|---|---|---|
wrote | no | True when a row was written. With if_absent=true this is false if the key already existed (nothing was changed). |
previous | no | The prior value before this call ("" when the key was absent), for idempotency reporting. |
{"signatures":{"go":"func (x *AdminClient) UpsertSystemSetting(ctx context.Context, req *adminv1.UpsertSystemSettingRequest) (*adminv1.UpsertSystemSettingResponse, error)","python":"upsert_system_setting(req: admin_pb2.UpsertSystemSettingRequest) -\u003e UpsertSystemSettingResponse","typescript":"upsertSystemSetting(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.UpsertSystemSettingRequestSchema\u003e): Promise\u003cUpsertSystemSettingResponse\u003e","curl":"curl -X PUT \"${AGENTROUTER_BASE_URL}/admin/v1/system-settings/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"value\": \"...\",\n \"if_absent\": false\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.UpsertSystemSettingRequest{}\n\n\tresp, err := client.Admin().UpsertSystemSetting(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/upsertsystemsetting\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.UpsertSystemSettingRequest()\ntry:\n result = client.admin.upsert_system_setting(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.upsertSystemSetting(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X PUT \"${AGENTROUTER_BASE_URL}/admin/v1/system-settings/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"value\": \"...\",\n \"if_absent\": false\n }'"},"persona":"Admin","httpVerb":"PUT","httpPath":"/admin/v1/system-settings/{key}","slug":"upsert-system-setting"}
Clear system setting
Changed in v0.9.0 (new features): Data planes now carry stored_url, the URL stored for the data plane. When another organization uses the same data plane ID, stored_url is the first hostname your data plane declares, or empty. The new ClearSystemSetting unsets the proxy URL setting or the stored URL of one data plane.
Changed in v0.9.0 (deprecations): stored_url on data planes and ClearSystemSetting are deprecated. They go with the stored data plane URL in a later release.
Deprecated
What it does: Stores an empty value under a URL key, which then reads back as not-found (tetrateio/fraser#7281). UpsertSystemSetting rejects an empty value, so this is the API write that unsets a URL. Only the "proxy-url" key and the "dataplane-url:<data plane ID>" keys are accepted; any other key returns InvalidArgument. A clear of a "dataplane-url:" key is refused with FailedPrecondition when another organization uses the same data plane ID, like SetDataplaneURL. It leaves the data plane's default Project Gateway unchanged and sends the data plane its new URL configuration. Deprecated: a data plane declares its own hostnames from 0.7, and this goes with the stored data plane URL in a later release.
Request fields:
| Field | Required | Description |
|---|---|---|
key | no | Key to clear. Only "proxy-url" and "dataplane-url:<data plane ID>" are accepted; any other key returns InvalidArgument. |
Response fields:
| Field | Required | Description |
|---|---|---|
previous | no | The value before this call ("" when the key was absent or already clear). |
{"signatures":{"go":"func (x *AdminClient) ClearSystemSetting(ctx context.Context, req *adminv1.ClearSystemSettingRequest) (*adminv1.ClearSystemSettingResponse, error)","python":"clear_system_setting(req: admin_pb2.ClearSystemSettingRequest) -\u003e ClearSystemSettingResponse","typescript":"clearSystemSetting(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ClearSystemSettingRequestSchema\u003e): Promise\u003cClearSystemSettingResponse\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/system-settings/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ClearSystemSettingRequest{}\n\n\tresp, err := client.Admin().ClearSystemSetting(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/clearsystemsetting\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ClearSystemSettingRequest()\ntry:\n result = client.admin.clear_system_setting(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.clearSystemSetting(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/admin/v1/system-settings/01H...\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"DELETE","httpPath":"/admin/v1/system-settings/{key}","slug":"clear-system-setting"}
List dataplane rollout
Changed in v0.7.0 (new features): Rollout progress now reads per data plane as a fraction of its labelled projects, and rolls up to a fleet figure such as 7 of 9 that counts a data plane only when every project on it holds its current revision. Projects with no revision yet are left out of both, so a data plane serving only those reads 0 of 0. Each data plane also reports whether its guardrails union is current, beside those counts rather than folded into them.
What it does: Reads the rollout watermark per data plane and rolls it up to a fleet figure, which is the reading a platform admin watches a change land by. It counts against the per-project revision #8587 mints and introduces no counter of its own. A data plane is current when every project labelled on it holds that project's current revision, so the fleet figure is a count of data planes rather than of projects.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Required: the customer whose fleet this is. |
dataplane_ids | no | Optional: report only these data planes. Empty reports every data plane carrying at least one project label. |
Response fields:
| Field | Required | Description |
|---|---|---|
dataplanes | no | One line per data plane, ordered by data plane id. |
dataplanes_current | no | The fleet figure, which is "7/9 data planes": how many data planes hold the current revision for EVERY project labelled on them, out of how many carry a label at all. A data plane with no labels is in neither number, and neither is a data plane listed at 0 of 0 because none of its projects has a revision yet: no revision was distributed to it, so it has no rollout to have finished. |
dataplanes_labelled | no | undocumented |
{"signatures":{"go":"func (x *AdminClient) ListDataplaneRollout(ctx context.Context, req *adminv1.ListDataplaneRolloutRequest) (*adminv1.ListDataplaneRolloutResponse, error)","python":"list_dataplane_rollout(req: admin_pb2.ListDataplaneRolloutRequest) -\u003e ListDataplaneRolloutResponse","typescript":"listDataplaneRollout(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListDataplaneRolloutRequestSchema\u003e): Promise\u003cListDataplaneRolloutResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../dataplanes:rollout\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListDataplaneRolloutRequest{}\n\n\tresp, err := client.Admin().ListDataplaneRollout(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listdataplanerollout\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListDataplaneRolloutRequest()\ntry:\n result = client.admin.list_dataplane_rollout(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listDataplaneRollout(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../dataplanes:rollout\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\""},"persona":"Admin","httpVerb":"GET","httpPath":"/admin/v1/customers/{customer_id}/dataplanes:rollout","slug":"list-dataplane-rollout"}
List projects served from
Changed in v0.7.0 (new features): You can now resolve a set of data planes to the projects served from them, so a region-bound rule attaches to those projects rather than to the infrastructure. Each project also reports the data planes outside your selection that serve it, because a project labelled in several regions is served from all of them. Nothing verifies that a data plane named for a region runs in it.
What it does: Resolves a set of data planes to the projects served from them, which is what a region-bound rule attaches to. The rule attaches to the projects rather than to the data planes on purpose. A project is deliberately labelled on data planes in several regions, because that is the HA mechanism, so a control anchored to infrastructure would reach every region the project is served from. Each project here therefore reports the selected data planes serving it AND the ones outside the selection, so an operator sees which projects the selection does not contain. Nothing verifies where a data plane runs. A region lives in the name an operator gave the data plane and in the address it reports, both of which are the operator's own strings, mirrored read-only.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Required: the customer whose data planes these are. |
dataplane_ids | yes | Required: the data planes the selection names. An operator picks them by the region in their names, and nothing checks that a data plane named for a region runs in it. |
Response fields:
| Field | Required | Description |
|---|---|---|
projects | no | The projects served from the selection, ordered by project slug. |
dataplanes_serving_nothing | no | Selected data plane ids that carry no project label, ordered. They are reported rather than dropped: a selection that reaches nothing is a typo or a data plane serving nobody, and both are worth seeing. |
{"signatures":{"go":"func (x *AdminClient) ListProjectsServedFrom(ctx context.Context, req *adminv1.ListProjectsServedFromRequest) (*adminv1.ListProjectsServedFromResponse, error)","python":"list_projects_served_from(req: admin_pb2.ListProjectsServedFromRequest) -\u003e ListProjectsServedFromResponse","typescript":"listProjectsServedFrom(req: MessageInitShape\u003ctypeof tars_admin_v1_admin_pb.ListProjectsServedFromRequestSchema\u003e): Promise\u003cListProjectsServedFromResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../dataplanes:projectsServedFrom\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"dataplane_ids\": []\n }'"},"examples":{"go":{"files":[{"name":"main.go","content":"// Command example is a runnable example for the AgentRouter Go SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then `go run .`.\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\tagentrouter \"github.com/tetrateio/agentrouter-go\"\n\tadminv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/admin/v1\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\tclient, err := agentrouter.New(ctx,\n\t\tagentrouter.WithBaseURL(os.Getenv(\"AGENTROUTER_BASE_URL\")),\n\t\tagentrouter.WithAPIKey(os.Getenv(\"AGENTROUTER_API_KEY\")),\n\t)\n\tif err != nil {\n\t\tlog.Fatalf(\"client: %v\", err)\n\t}\n\n\t// Populate the request fields -- see the \"Request fields\" table above for\n\t// the available fields and which are required.\n\treq := \u0026adminv1.ListProjectsServedFromRequest{}\n\n\tresp, err := client.Admin().ListProjectsServedFrom(ctx, req)\n\tif err != nil {\n\t\tlog.Fatalf(\"call: %v\", err)\n\t}\n\n\tfmt.Printf(\"%+v\\n\", resp)\n}\n"},{"name":"go.mod","content":"module github.com/tetrateio/agentrouter-go-examples/admin/listprojectsservedfrom\n\ngo 1.26\n\nrequire github.com/tetrateio/agentrouter-go v0.1.1\n\n// Point this at the directory you extracted the downloaded Go SDK tarball into.\n// The directory name matches the tarball stem on the Download SDK page.\nreplace github.com/tetrateio/agentrouter-go =\u003e ./third_party/agentrouter-go-0.1.1\n"}]},"python":{"files":[{"name":"main.py","content":"\"\"\"Runnable example for the AgentRouter Python SDK.\n\nSet AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `python main.py`.\n\"\"\"\nimport os\n\nfrom tars.admin.v1 import admin_pb2\n\nfrom agentrouter_sdk import Client\n\nclient = Client(\n base_url=os.environ[\"AGENTROUTER_BASE_URL\"],\n api_key=os.environ[\"AGENTROUTER_API_KEY\"],\n)\n\n# Populate the request fields -- see the \"Request fields\" table above\n# for the available fields and which are required.\nreq = admin_pb2.ListProjectsServedFromRequest()\ntry:\n result = client.admin.list_projects_served_from(req)\n print(result)\nexcept Exception as err:\n print(\"Error:\", err)\n"},{"name":"requirements.txt","content":"# Point this at the directory you extracted the downloaded Python SDK tarball\n# into. The directory name matches the tarball stem on the Download SDK page.\n# To install instead from PyPI once published, replace the line below with:\n# agentrouter-sdk\u003e=0.1.0\nagentrouter-sdk @ file:./third_party/agentrouter-python-0.1.1\n"}]},"typescript":{"files":[{"name":"index.ts","content":"// Runnable example for the AgentRouter TypeScript SDK.\n// Set AGENTROUTER_BASE_URL and AGENTROUTER_API_KEY in the environment, then run `npm install \u0026\u0026 npx tsx index.ts`.\nimport { Client } from '@tetrate/agentrouter-sdk'\n\nconst client = new Client({\n baseUrl: process.env.AGENTROUTER_BASE_URL,\n apiKey: process.env.AGENTROUTER_API_KEY,\n})\n\n// Populate the request fields -- see the \"Request fields\" table above\n// for the available fields and which are required.\nconst req = {}\ntry {\n const result = await client.admin.listProjectsServedFrom(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"admin\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"dependencies\": {\n \"@tetrate/agentrouter-sdk\": \"file:./third_party/agentrouter-typescript-0.1.1\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"typescript\": \"^5.4.0\"\n }\n}\n"},{"name":"tsconfig.json","content":"{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"bundler\",\n \"strict\": true,\n \"esModuleInterop\": true,\n \"skipLibCheck\": true\n }\n}\n"}]},"curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/admin/v1/customers/cust_01H.../dataplanes:projectsServedFrom\" \\\n -H \"Authorization: Bearer ak-${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"dataplane_ids\": []\n }'"},"persona":"Admin","httpVerb":"POST","httpPath":"/admin/v1/customers/{customer_id}/dataplanes:projectsServedFrom","slug":"list-projects-served-from"}