Summary
The cloud-api has two inconsistent naming/identifier conventions, depending on which endpoint family you're hitting:
1. camelCase vs snake_case
| Convention |
Endpoints |
Example fields |
| snake_case |
OpenAI-compat: /v1/chat/completions, /v1/responses, /v1/embeddings, /v1/files, /v1/audio/*, /v1/images/*, /v1/rerank, /v1/conversations, ... |
prompt_tokens, tool_calls, finish_reason, created_at, system_fingerprint |
| camelCase |
/v1/admin/*, /v1/billing/*, /v1/services/*, /v1/workspaces/*, /v1/model/{model_name} |
requestIds, costPerImage, cacheReadCostPerToken, createdAt, isActive, displayName, spendLimit |
Per the OpenAPI spec, 114 distinct camelCase fields appear across 14 paths. Clients porting from OpenAI conventions (or using snake_case-by-default JSON serializers) hit unexpected missing field errors on the admin/billing side.
2. Identifier prefix mismatch
The id field returned in chat completion responses includes a chatcmpl- prefix:
{"id":"chatcmpl-d53bfb7d-8eb3-4750-bd90-94a1365f906c", ...}
But /v1/billing/costs expects the stripped UUID (no prefix):
# WRONG — uses the same id from the response
curl -s -X POST https://cloud-api.near.ai/v1/billing/costs \
-d '{"requestIds":["chatcmpl-d53bfb7d-8eb3-4750-bd90-94a1365f906c"]}'
# HTTP 422 "UUID parsing failed: invalid character: found `h` at 2"
# CORRECT — strip the prefix
curl -s -X POST https://cloud-api.near.ai/v1/billing/costs \
-d '{"requestIds":["d53bfb7d-8eb3-4750-bd90-94a1365f906c"]}'
# HTTP 200 {"requests":[{"requestId":"...","costNanoUsd":0}]}
A user looking up costs for chat IDs they've kept track of must know to strip the prefix — undocumented.
Suggested fix
Naming:
- Pick one convention per surface and stick to it. If the admin/billing/services surfaces are considered private (UI-internal), document them that way. If they're part of the public OpenAPI, normalize to snake_case to match the rest.
- Alternative: serde-rename camelCase fields to snake_case in the JSON layer while keeping the internal Rust struct camelCase. Single source of truth.
Identifiers:
- Either accept
chatcmpl- prefix on billing lookups, OR strip the prefix in response IDs. The mismatch is the bug.
- Either way, document the format clearly in the OpenAPI
description.
Notable affected admin/billing paths
/v1/admin/models, /v1/admin/models/{model_name}, /v1/admin/models/deprecate,
/v1/admin/organizations/{org_id}/concurrent-limit,
/v1/admin/organizations/{org_id}/limits,
/v1/admin/services, /v1/admin/services/{id},
/v1/billing/costs, /v1/model/{model_name},
/v1/services/{service_name},
/v1/workspaces/{workspace_id}/api-keys,
/v1/workspaces/{workspace_id}/api-keys/{key_id},
/v1/workspaces/{workspace_id}/api-keys/{key_id}/spend-limit
Found during routine cloud-api smoke test.
Summary
The cloud-api has two inconsistent naming/identifier conventions, depending on which endpoint family you're hitting:
1. camelCase vs snake_case
/v1/chat/completions,/v1/responses,/v1/embeddings,/v1/files,/v1/audio/*,/v1/images/*,/v1/rerank,/v1/conversations, ...prompt_tokens,tool_calls,finish_reason,created_at,system_fingerprint/v1/admin/*,/v1/billing/*,/v1/services/*,/v1/workspaces/*,/v1/model/{model_name}requestIds,costPerImage,cacheReadCostPerToken,createdAt,isActive,displayName,spendLimitPer the OpenAPI spec, 114 distinct camelCase fields appear across 14 paths. Clients porting from OpenAI conventions (or using snake_case-by-default JSON serializers) hit unexpected
missing fielderrors on the admin/billing side.2. Identifier prefix mismatch
The
idfield returned in chat completion responses includes achatcmpl-prefix:{"id":"chatcmpl-d53bfb7d-8eb3-4750-bd90-94a1365f906c", ...}But
/v1/billing/costsexpects the stripped UUID (no prefix):A user looking up costs for chat IDs they've kept track of must know to strip the prefix — undocumented.
Suggested fix
Naming:
Identifiers:
chatcmpl-prefix on billing lookups, OR strip the prefix in response IDs. The mismatch is the bug.description.Notable affected admin/billing paths
Found during routine cloud-api smoke test.