{"slug": "gcp-billing-vertex-ai-solving-gemini-cost-allocation-in-a-single-project-vertex", "title": "[GCP Billing & Vertex AI] Solving Gemini Cost Allocation in a Single Project: Vertex AI Dynamic Billing Labels in Action", "summary": "A developer solved Gemini cost allocation within a single GCP project by switching from API Keys to Vertex AI calls and using dynamic request labels. By adding custom labels like client_id to each Vertex AI generateContent request, the team enabled per-client billing breakdown in GCP reports. The refactoring involved modifying 19 call points across 11 files in a LINE Bot project.", "body_md": "When developing enterprise-level LLM services or operating multi-tenant platforms, the question most frequently asked by finance and operations teams is:\n\n\"We have many different business lines and LINE Bots connected within the same GCP project. Every day, the Gemini Key costs all appear under the Gemini API category. Is there a way for us to split the costs based on different Gemini Keys or different users?\"\n\n**Direct answer to your question:** In Google Cloud Billing reports, it is **not possible to directly display costs \"based on different API Key names.\"** The smallest attribution dimensions for Google Cloud billing reports are \"Project,\" \"Service,\" and \"SKU (Product Line Item).\" The system does not treat individual API Key strings as independent billing items. For the billing system, whether you create 10 or 100 API Keys within the same project, they will all be lumped together as a single Gemini API total.\n\nIf architectural constraints force you to stay within the same project, the most recommended approach is: **switch to Vertex AI calls and use \"Request Labels.\"**\n\nIf you are currently using a Google AI Studio API Key, it cannot pass billing labels within a single project. However, if you change your code to call the **Vertex AI Gemini API** (still within the same project), Vertex AI supports dynamically including custom `labels`\n\nwith each request.\n\nWhen sending each request (e.g., calling `generateContent`\n\n), include specific metadata in the API Request:\n\n```\n{\n  \"contents\": { ... },\n  \"labels\": {\n    \"client_id\": \"info_helper\",\n    \"api_key_group\": \"marketing_team\"\n  }\n}\n```\n\nThese custom labels are passed directly to the GCP billing system. Later, when you go to the GCP Billing report and select your set label key (e.g., `client_id`\n\n) in \"Group by,\" you can clearly see the costs for different labels (representing different services, clients, or users) within the same project!\n\nTo fulfill this requirement, we audited the current API call architecture of the LINE Bot project and performed the following refactoring.\n\nThrough scanning, we found that the vast majority of calls in the project use Vertex AI (14 out of 17 clients use `vertexai=True`\n\n), with only a few exceptions:\n\n`main.py`\n\n, Batch service in `batch_service.py`\n\n, and TTS speech synthesis in `tts_tool.py`\n\n.[!IMPORTANT] The\n\n`labels`\n\nparameter is only supported by Vertex AI. If this parameter is included under an API Key (`vertexai=False`\n\n), it will cause the SDK to throw an error. Therefore, we only modified the 11 files that use Vertex AI.\n\nFor the `google-genai`\n\nPython SDK, we have two main modification scenarios:\n\n`GenerateContentConfig`\n\nIf the original call already includes a Config, we just need to pass an additional `labels={\"client_id\": \"info_helper\"}`\n\ninto the config:\n\n```\n# Before (e.g., loader/gh_tools.py)\nresponse = client.models.generate_content(\n    model=\"gemini-2.5-flash\",\n    contents=prompt,\n    config=types.GenerateContentConfig(\n        temperature=0,\n        max_output_tokens=2048,\n    )\n)\n\n# After\nresponse = client.models.generate_content(\n    model=\"gemini-2.5-flash\",\n    contents=prompt,\n    config=types.GenerateContentConfig(\n        temperature=0,\n        max_output_tokens=2048,\n        labels={\"client_id\": \"info_helper\"}, # Include billing label\n    )\n)\n```\n\nIf the original call is very simple (e.g., `searchtool.py`\n\nor `youtube_gcp.py`\n\n), we need to proactively include a `GenerateContentConfig`\n\ncontaining labels:\n\n```\n# Before (e.g., loader/searchtool.py)\nresponse = client.models.generate_content(\n    model=\"gemini-3.1-flash-lite-preview\",\n    contents=prompt,\n)\n\n# After\nresponse = client.models.generate_content(\n    model=\"gemini-3.1-flash-lite-preview\",\n    contents=prompt,\n    config=types.GenerateContentConfig(\n        labels={\"client_id\": \"info_helper\"}, # Add config to include label\n    ),\n)\n```\n\nWe performed precise modifications on a total of 19 call points across the following 11 files, and used Python's AST module (`ast.parse`\n\n) and Flake8 for syntax and formatting checks before submission:\n\n`_create_chat_config()`\n\nto add labels to both general Q&A and Grounding conversations.When refactoring calls without Config for `youtube_gcp.py`\n\nand `youtube_tool.py`\n\n, since these two files originally only used named imports for specific types:\n\n``` python\nfrom google.genai.types import HttpOptions, Part\n```\n\nWhen we write `types.GenerateContentConfig(...)`\n\nin the code, the system throws a `NameError: name 'types' is not defined`\n\nerror.\n\n**Solution:** We need to correct the import statement and directly import [GenerateContentConfig]:\n\n``` python\n# Before\nfrom google.genai.types import HttpOptions, Part\n\n# After\nfrom google.genai.types import HttpOptions, Part, GenerateContentConfig\n```\n\nAnd use it directly in the call without the `types.`\n\nprefix:\n\n```\nconfig=GenerateContentConfig(labels={\"client_id\": \"info_helper\"})\n```\n\nThis modification successfully injected the `client_id=info_helper`\n\nlabel into all Vertex AI API calls within the LINE Bot project.\n\n`labels`\n\n, GCP billing data usually has a 24 to 48-hour delay before taking effect.`client_id`\n\n.`info_helper`\n\nas a separate billing row, perfectly solving the problem of separating project costs for reimbursement and statistics!", "url": "https://wpnews.pro/news/gcp-billing-vertex-ai-solving-gemini-cost-allocation-in-a-single-project-vertex", "canonical_source": "https://dev.to/gde/gcp-billing-vertex-ai-solving-gemini-cost-allocation-in-a-single-project-vertex-ai-dynamic-5aok", "published_at": "2026-07-12 15:09:09+00:00", "updated_at": "2026-07-12 15:15:49.217622+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-infrastructure", "developer-tools"], "entities": ["Google Cloud", "Vertex AI", "Gemini", "GCP"], "alternates": {"html": "https://wpnews.pro/news/gcp-billing-vertex-ai-solving-gemini-cost-allocation-in-a-single-project-vertex", "markdown": "https://wpnews.pro/news/gcp-billing-vertex-ai-solving-gemini-cost-allocation-in-a-single-project-vertex.md", "text": "https://wpnews.pro/news/gcp-billing-vertex-ai-solving-gemini-cost-allocation-in-a-single-project-vertex.txt", "jsonld": "https://wpnews.pro/news/gcp-billing-vertex-ai-solving-gemini-cost-allocation-in-a-single-project-vertex.jsonld"}}