AI Keys (BYOK)
Package: agentrouter.aikeys.v1 Service: AiKeysService
Endpoints
Register an AI key
Changed in v0.1.5 (bug fixes): Project members can again register, list, and revoke their own user-scoped AI provider keys. The permission-only AI-key endpoints rejected members after the RBAC migration even though their role was intended to carry those permissions. Shared project keys remain owner-controlled.
What it does: Encrypts and stores a provider API key under a project. After this call, inference requests routed to the matching provider for this project will use this key. Scope: account-tier so any project member can register their OWN user-scoped key (user_scope=true). Registering a PROJECT-level key (user_scope=false) additionally requires the caller to be the project's owner -- enforced in-handler against project_members.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Defaults to the caller's session customer when empty. |
project_id | no | Defaults to the caller's session project when empty. |
provider | yes | Provider this key authenticates against. |
name | yes | Operator-supplied label for the key, e.g. "openai-prod". |
secret | yes | Plaintext provider key, e.g. sk-.... Sent over TLS only; the server immediately wraps with secrets-svc and discards the plaintext. |
user_scope | no | user_scope registers a per-user key private to the caller that overrides the project key for the caller's inference traffic. When false (default) the key is project-level (shared) and requires the caller to be the project owner. |
Response fields:
| Field | Required | Description |
|---|---|---|
key | no | The newly registered key's metadata record (no plaintext). |
{"signatures":{"go":"func (x *AiKeysClient) Register(ctx context.Context, req *aikeysv1.RegisterRequest) (*aikeysv1.RegisterResponse, error)","python":"register(req: aikeys_pb2.RegisterRequest) -\u003e RegisterResponse","typescript":"register(req: MessageInitShape\u003ctypeof tars_aikeys_v1_aikeys_pb.RegisterRequestSchema\u003e): Promise\u003cRegisterResponse\u003e","cli":"tare api byok add --provider $PROVIDER --name $NAME --secret $SECRET","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../aikeys\" \\\n -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"provider\": \"...\",\n \"name\": \"...\",\n \"secret\": \"...\",\n \"user_scope\": 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\taikeysv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/aikeys/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 := \u0026aikeysv1.RegisterRequest{}\n\n\tresp, err := client.AiKeys().Register(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/aikeys/register\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.aikeys.v1 import aikeys_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 = aikeys_pb2.RegisterRequest()\ntry:\n result = client.ai_keys.register(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.aiKeys.register(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"aikeys\",\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"}]},"cli":"tare api byok add --provider $PROVIDER --name $NAME --secret $SECRET","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../aikeys\" \\\n -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"provider\": \"...\",\n \"name\": \"...\",\n \"secret\": \"...\",\n \"user_scope\": false\n }'"},"persona":"Authenticated (API key or session token)","httpVerb":"POST","httpPath":"/v1/customers/{customer_id}/projects/{project_id}/aikeys","slug":"register-an-ai-key"}
Get an AI key
What it does: Returns the metadata record for a single BYOK key. Never returns the plaintext. Scope: account-tier. Any project member may read keys in the project (project-level and the caller's own user-scoped keys); membership is enforced in-handler.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Defaults to the caller's session customer when empty. |
project_id | no | Defaults to the caller's session project when empty. |
id | yes | byok_<ulid> identifying the key to fetch. |
Response fields:
| Field | Required | Description |
|---|---|---|
key | no | The requested key's metadata record (no plaintext). |
{"signatures":{"go":"func (x *AiKeysClient) Get(ctx context.Context, req *aikeysv1.GetRequest) (*aikeysv1.GetResponse, error)","python":"get(req: aikeys_pb2.GetRequest) -\u003e GetResponse","typescript":"get(req: MessageInitShape\u003ctypeof tars_aikeys_v1_aikeys_pb.GetRequestSchema\u003e): Promise\u003cGetResponse\u003e","cli":"tare api byok get \u003cid\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../aikeys/01H...\" \\\n -H \"Authorization: Bearer ${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\taikeysv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/aikeys/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 := \u0026aikeysv1.GetRequest{}\n\n\tresp, err := client.AiKeys().Get(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/aikeys/get\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.aikeys.v1 import aikeys_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 = aikeys_pb2.GetRequest()\ntry:\n result = client.ai_keys.get(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.aiKeys.get(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"aikeys\",\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"}]},"cli":"tare api byok get \u003cid\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../aikeys/01H...\" \\\n -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"persona":"Authenticated (API key or session token)","httpVerb":"GET","httpPath":"/v1/customers/{customer_id}/projects/{project_id}/aikeys/{id}","slug":"get-an-ai-key"}
List AI keys
Changed in v0.1.5 (bug fixes): Project members can again register, list, and revoke their own user-scoped AI provider keys. The permission-only AI-key endpoints rejected members after the RBAC migration even though their role was intended to carry those permissions. Shared project keys remain owner-controlled.
What it does: Lists BYOK keys registered under a project. Returns metadata only -- id, provider, name, display_suffix, creation timestamp, and revocation timestamp if revoked. The result includes the project's shared keys plus the caller's own user-scoped keys (other users' user-scoped keys are not returned). Scope: account-tier; membership is enforced in-handler.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Defaults to the caller's session customer when empty. |
project_id | no | Defaults to the caller's session project when empty. |
Response fields:
| Field | Required | Description |
|---|---|---|
keys | no | All keys registered under the project (metadata only, no plaintext). |
{"signatures":{"go":"func (x *AiKeysClient) List(ctx context.Context, req *aikeysv1.ListRequest) (*aikeysv1.ListResponse, error)","python":"list(req: aikeys_pb2.ListRequest) -\u003e ListResponse","typescript":"list(req: MessageInitShape\u003ctypeof tars_aikeys_v1_aikeys_pb.ListRequestSchema\u003e): Promise\u003cListResponse\u003e","cli":"tare api byok list","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../aikeys\" \\\n -H \"Authorization: Bearer ${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\taikeysv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/aikeys/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 := \u0026aikeysv1.ListRequest{}\n\n\tresp, err := client.AiKeys().List(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/aikeys/list\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.aikeys.v1 import aikeys_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 = aikeys_pb2.ListRequest()\ntry:\n result = client.ai_keys.list(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.aiKeys.list(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"aikeys\",\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"}]},"cli":"tare api byok list","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../aikeys\" \\\n -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"persona":"Authenticated (API key or session token)","httpVerb":"GET","httpPath":"/v1/customers/{customer_id}/projects/{project_id}/aikeys","slug":"list-ai-keys"}
Revoke an AI key
Changed in v0.1.5 (bug fixes): Project members can again register, list, and revoke their own user-scoped AI provider keys. The permission-only AI-key endpoints rejected members after the RBAC migration even though their role was intended to carry those permissions. Shared project keys remain owner-controlled.
What it does: Marks the key revoked; subsequent Fetches return permission_denied. Inflight cached keys on dataplanes invalidate within sub-second via the revocation channel (milestone C). Scope: account-tier so a member can revoke their OWN user-scoped key. Revoking a PROJECT-level key additionally requires project ownership (enforced in-handler); a member may never revoke another user's user-scoped key.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Defaults to the caller's session customer when empty. |
project_id | no | Defaults to the caller's session project when empty. |
id | yes | byok_<ulid> identifying the key to revoke. |
{"signatures":{"go":"func (x *AiKeysClient) Revoke(ctx context.Context, req *aikeysv1.RevokeRequest) (*aikeysv1.RevokeResponse, error)","python":"revoke(req: aikeys_pb2.RevokeRequest) -\u003e RevokeResponse","typescript":"revoke(req: MessageInitShape\u003ctypeof tars_aikeys_v1_aikeys_pb.RevokeRequestSchema\u003e): Promise\u003cRevokeResponse\u003e","cli":"tare api byok remove \u003cid\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../aikeys/01H...\" \\\n -H \"Authorization: Bearer ${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\taikeysv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/aikeys/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 := \u0026aikeysv1.RevokeRequest{}\n\n\tresp, err := client.AiKeys().Revoke(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/aikeys/revoke\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.aikeys.v1 import aikeys_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 = aikeys_pb2.RevokeRequest()\ntry:\n result = client.ai_keys.revoke(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.aiKeys.revoke(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"aikeys\",\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"}]},"cli":"tare api byok remove \u003cid\u003e","curl":"curl -X DELETE \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../aikeys/01H...\" \\\n -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"persona":"Authenticated (API key or session token)","httpVerb":"DELETE","httpPath":"/v1/customers/{customer_id}/projects/{project_id}/aikeys/{id}","slug":"revoke-an-ai-key"}
Get AI key traffic settings
What it does: Returns the BYOK traffic pool for one provider in a project: every key the caller's own inference traffic can be served by, with its stored traffic_weight / traffic_order / traffic_preference. The pool is the UNION the route generator actually builds for the caller (materializedBYOKKeys): the caller's legacy per-user keys plus the project's effective keys for the provider (the caller's own user-scoped keys when they have any, otherwise the project-level keys). Revoked rows are excluded -- they have no dataplane backend, so they must neither absorb a share of a split nor appear in a failover ladder. Scope: account-tier; membership is enforced in-handler.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Defaults to the caller's session customer when empty. |
project_id | no | Defaults to the caller's session project when empty. |
provider | yes | Provider whose pool to read. |
Response fields:
| Field | Required | Description |
|---|---|---|
settings | no | The pool, legacy keys first and oldest first within each leg -- the same order the route generator sees them in. |
{"signatures":{"go":"func (x *AiKeysClient) GetTrafficSettings(ctx context.Context, req *aikeysv1.GetTrafficSettingsRequest) (*aikeysv1.GetTrafficSettingsResponse, error)","python":"get_traffic_settings(req: aikeys_pb2.GetTrafficSettingsRequest) -\u003e GetTrafficSettingsResponse","typescript":"getTrafficSettings(req: MessageInitShape\u003ctypeof tars_aikeys_v1_aikeys_pb.GetTrafficSettingsRequestSchema\u003e): Promise\u003cGetTrafficSettingsResponse\u003e","curl":"curl \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../aikeys:traffic\" \\\n -H \"Authorization: Bearer ${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\taikeysv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/aikeys/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 := \u0026aikeysv1.GetTrafficSettingsRequest{}\n\n\tresp, err := client.AiKeys().GetTrafficSettings(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/aikeys/gettrafficsettings\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.aikeys.v1 import aikeys_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 = aikeys_pb2.GetTrafficSettingsRequest()\ntry:\n result = client.ai_keys.get_traffic_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.aiKeys.getTrafficSettings(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"aikeys\",\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}/v1/customers/cust_01H.../projects/proj_01H.../aikeys:traffic\" \\\n -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\""},"persona":"Authenticated (API key or session token)","httpVerb":"GET","httpPath":"/v1/customers/{customer_id}/projects/{project_id}/aikeys:traffic","slug":"get-ai-key-traffic-settings"}
Update AI key traffic settings
What it does: Rewrites the placement of keys in one provider's BYOK pool -- the load-balance weights, the failover order, and the pool-wide usage preference. Only rows the caller OWNS are writable: a shared project key another member registered is returned by GetTrafficSettings (it serves the caller's traffic) but naming it here is rejected rather than silently dropped. Rows the request does not name keep their current placement. Scope: account-tier; membership is enforced in-handler, and rewriting a PROJECT-level (shared) key additionally requires project ownership -- the same split Register and Revoke apply.
Request fields:
| Field | Required | Description |
|---|---|---|
customer_id | no | Defaults to the caller's session customer when empty. |
project_id | no | Defaults to the caller's session project when empty. |
provider | yes | Provider whose pool to rewrite. |
preference | no | Pool-wide usage preference ("always", "primary" or "fallback") applied to every writable row. Unset leaves each row's preference alone. It is pool-wide because a mixed pool is order-dependent downstream: the route context takes the FIRST parseable policy per provider, so one dissenting row would decide the whole provider's BYOK policy. |
settings | no | Placements to write. Only key_id, weight and order are read; the OUTPUT_ONLY fields are ignored. Every entry must name a key in the caller's pool that the caller owns -- an unknown or unwritable key fails the whole request rather than being dropped. Rows the request does not name keep their current weight and order. |
Response fields:
| Field | Required | Description |
|---|---|---|
settings | no | The pool as it stands after the write, in the same order GetTrafficSettings returns it. |
{"signatures":{"go":"func (x *AiKeysClient) UpdateTrafficSettings(ctx context.Context, req *aikeysv1.UpdateTrafficSettingsRequest) (*aikeysv1.UpdateTrafficSettingsResponse, error)","python":"update_traffic_settings(req: aikeys_pb2.UpdateTrafficSettingsRequest) -\u003e UpdateTrafficSettingsResponse","typescript":"updateTrafficSettings(req: MessageInitShape\u003ctypeof tars_aikeys_v1_aikeys_pb.UpdateTrafficSettingsRequestSchema\u003e): Promise\u003cUpdateTrafficSettingsResponse\u003e","curl":"curl -X POST \"${AGENTROUTER_BASE_URL}/v1/customers/cust_01H.../projects/proj_01H.../aikeys:traffic\" \\\n -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"provider\": \"...\",\n \"preference\": \"...\",\n \"settings\": []\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\taikeysv1 \"github.com/tetrateio/agentrouter-go/genapi/api/tars/aikeys/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 := \u0026aikeysv1.UpdateTrafficSettingsRequest{}\n\n\tresp, err := client.AiKeys().UpdateTrafficSettings(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/aikeys/updatetrafficsettings\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.aikeys.v1 import aikeys_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 = aikeys_pb2.UpdateTrafficSettingsRequest()\ntry:\n result = client.ai_keys.update_traffic_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.aiKeys.updateTrafficSettings(req)\n console.log(result)\n} catch (err) {\n console.error('Error:', err)\n}\n"},{"name":"package.json","content":"{\n \"name\": \"aikeys\",\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}/v1/customers/cust_01H.../projects/proj_01H.../aikeys:traffic\" \\\n -H \"Authorization: Bearer ${AGENTROUTER_API_KEY}\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"provider\": \"...\",\n \"preference\": \"...\",\n \"settings\": []\n }'"},"persona":"Authenticated (API key or session token)","httpVerb":"POST","httpPath":"/v1/customers/{customer_id}/projects/{project_id}/aikeys:traffic","slug":"update-ai-key-traffic-settings"}