@rawdash/connector-openai
v0.27.0
Published
Rawdash connector for OpenAI — daily token usage, request counts, and spend from the OpenAI Usage and Costs admin APIs
Readme
@rawdash/connector-openai
Track OpenAI spend, daily token usage, request counts, and image / audio volume from the OpenAI Usage and Costs admin APIs.
Install
npm install @rawdash/connector-openaiAuthentication
Authenticates with an OpenAI organization admin API key (sk-admin-). Admin keys are the only key class that can read the Usage and Costs endpoints; project- or user-scoped keys return 401.
- Open platform.openai.com -> Settings -> Admin keys and create a new admin key. Admin keys are organization-scoped, so create the key from the organization whose usage you want to read.
- Store the key as a secret (e.g. OPENAI_ADMIN_API_KEY).
- Reference it from config as
adminApiKey: secret("OPENAI_ADMIN_API_KEY"). - If the key has access to multiple organizations, set
organizationIdto disambiguate. SetprojectIdsto restrict the query to a subset of projects.
Configuration
| Field | Type | Required | Description |
| ---------------- | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| adminApiKey | secret | Yes | OpenAI organization admin API key (starts with sk-admin-). Generate one at platform.openai.com -> Settings -> Admin keys. Project / user-scoped keys cannot read the Usage API. |
| organizationId | string | No | OpenAI organization id (org_...). Set this when the admin key has access to multiple organizations to disambiguate the request. |
| projectIds | array | No | Restrict usage and cost queries to specific OpenAI project ids (proj_...). Omit to aggregate every project the admin key can see. |
| resources | array | No | Which OpenAI metric series to sync. Omit to sync all of them. Resources are grouped by upstream endpoint - enabling any one metric from a group fetches the endpoint once and writes every metric the group produces. |
| lookbackDays | number | No | How many days of usage history to fetch on a full sync. Defaults to 30. Capped at 180 since the Usage API rejects very long ranges per call. |
Resources
openai_completions_input_tokens(metric) - Daily input tokens consumed by Chat Completions and Responses API calls, including cached and audio input tokens.- Endpoint:
GET /v1/organization/usage/completions - Unit: tokens
- Granularity: daily
- Dimensions:
model,project_id,api_key_id,user_id,batch - Sample value is the total input_tokens for the bucket. input_cached_tokens and input_audio_tokens are mirrored in attributes so a cache-hit ratio (cached / total) can be computed at query time.
- Endpoint:
openai_completions_output_tokens(metric) - Daily output tokens generated by Chat Completions and Responses API calls, including audio output tokens.- Endpoint:
GET /v1/organization/usage/completions - Unit: tokens
- Granularity: daily
- Dimensions:
model,project_id,api_key_id,user_id,batch - Sample value is the total output_tokens for the bucket. output_audio_tokens is mirrored in attributes for audio-only breakdowns. Written alongside openai_completions_input_tokens from the same usage_completions API call.
- Endpoint:
openai_completions_requests(metric) - Daily count of Chat Completions / Responses API model requests, grouped by model and project.- Endpoint:
GET /v1/organization/usage/completions - Unit: requests
- Granularity: daily
- Dimensions:
model,project_id,api_key_id,user_id,batch - Written alongside openai_completions_input_tokens from the same usage_completions API call.
- Endpoint:
openai_embeddings_input_tokens(metric) - Daily input tokens consumed by the Embeddings API, grouped by model and project.- Endpoint:
GET /v1/organization/usage/embeddings - Unit: tokens
- Granularity: daily
- Dimensions:
model,project_id,api_key_id,user_id
- Endpoint:
openai_embeddings_requests(metric) - Daily count of Embeddings API model requests, grouped by model and project.- Endpoint:
GET /v1/organization/usage/embeddings - Unit: requests
- Granularity: daily
- Dimensions:
model,project_id,api_key_id,user_id - Written alongside openai_embeddings_input_tokens from the same usage_embeddings API call.
- Endpoint:
openai_images_count(metric) - Daily count of images generated or edited via the Images API, grouped by model, project, source, and size.- Endpoint:
GET /v1/organization/usage/images - Unit: images
- Granularity: daily
- Dimensions:
model,project_id,api_key_id,user_id,source,size
- Endpoint:
openai_images_requests(metric) - Daily count of Images API model requests, grouped by model, project, source, and size.- Endpoint:
GET /v1/organization/usage/images - Unit: requests
- Granularity: daily
- Dimensions:
model,project_id,api_key_id,user_id,source,size - Written alongside openai_images_count from the same usage_images API call.
- Endpoint:
openai_audio_speeches_characters(metric) - Daily characters synthesized via the Text-to-Speech (audio_speeches) API, grouped by model and project.- Endpoint:
GET /v1/organization/usage/audio_speeches - Unit: characters
- Granularity: daily
- Dimensions:
model,project_id,api_key_id,user_id
- Endpoint:
openai_audio_speeches_requests(metric) - Daily count of Text-to-Speech (audio_speeches) API model requests, grouped by model and project.- Endpoint:
GET /v1/organization/usage/audio_speeches - Unit: requests
- Granularity: daily
- Dimensions:
model,project_id,api_key_id,user_id - Written alongside openai_audio_speeches_characters from the same usage_audio_speeches API call.
- Endpoint:
openai_audio_transcriptions_seconds(metric) - Daily audio seconds transcribed via the Whisper / audio_transcriptions API, grouped by model and project.- Endpoint:
GET /v1/organization/usage/audio_transcriptions - Unit: seconds
- Granularity: daily
- Dimensions:
model,project_id,api_key_id,user_id
- Endpoint:
openai_audio_transcriptions_requests(metric) - Daily count of audio_transcriptions API model requests, grouped by model and project.- Endpoint:
GET /v1/organization/usage/audio_transcriptions - Unit: requests
- Granularity: daily
- Dimensions:
model,project_id,api_key_id,user_id - Written alongside openai_audio_transcriptions_seconds from the same usage_audio_transcriptions API call.
- Endpoint:
openai_cost_usd(metric) - Daily organization spend in USD, broken down by line item and project. Pulled from the OpenAI Costs admin API.- Endpoint:
GET /v1/organization/costs - Unit: USD
- Granularity: daily
- Dimensions:
line_item,project_id,organization_id,currency - The Costs API only supports 1d bucket_width and only reports USD amounts. Costs can be revised for a couple of days after the fact; incremental syncs refetch a short trailing window to pick up adjustments.
- Endpoint:
Example
import {
defineConfig,
defineDashboard,
defineMetric,
secret,
} from '@rawdash/core';
const openai = {
name: 'openai',
connectorId: 'openai',
config: {
adminApiKey: secret('OPENAI_ADMIN_API_KEY'),
},
};
export default defineConfig({
connectors: [openai],
dashboards: {
ai: defineDashboard({
widgets: {
spend_mtd: {
kind: 'stat',
title: 'OpenAI spend (last 30d)',
window: '30d',
metric: defineMetric({
connector: openai,
shape: 'metric',
name: 'openai_cost_usd',
fn: 'sum',
}),
},
tokens_today: {
kind: 'stat',
title: 'Input tokens today',
window: '1d',
metric: defineMetric({
connector: openai,
shape: 'metric',
name: 'openai_completions_input_tokens',
fn: 'sum',
}),
},
},
}),
},
});Rate limits
The Usage and Costs admin endpoints share an organization-wide rate limit; the connector backs off on standard x-ratelimit-* / 429 responses with Retry-After.
Limitations
- Only the Usage API (token, image, audio counts) and Costs API are synced. Per-request logs (Chat Completions, Embeddings, Images traffic) are not available through the admin Usage API.
- All samples are bucketed daily (1d bucket_width). Hourly granularity is supported by the Usage API but is not exposed here in v1.
- The Costs API only supports 1d bucket_width and reports cost in USD; non-USD billing currencies are not converted.
- Admin API keys are required - project- or user-scoped keys do not have access to the organization Usage and Costs endpoints.
Links
License
Apache-2.0
