OpenAI
The OpenAI Admin API exposes two kinds of organization-wide reporting: usage reports, one per API capability, and a daily cost report with amounts in USD. Usage reports cover completions, embeddings, images, audio, moderations, vector stores, and code interpreter sessions.
Renta syncs both to your data warehouse as time-bucketed statistics broken down by project, user, API key, and model.
Authentication
Renta authenticates with an organization Admin API key. Create one at platform.openai.com under Organization settings > Admin keys: the key starts with sk-admin. Regular project API keys are rejected by the Admin API reporting endpoints.
When you save the connection, Renta validates the key against the OpenAI Admin API, so an invalid or non-admin key returns an error immediately instead of failing on the first pipeline run.
Connect OpenAI source
- Navigate to the Connections > Catalog section in the left sidebar.
- Open the AI category and click the OpenAI card.

Fill in the connection form:
- Source name.
Specify a name for this data source. This is used exclusively in the Renta interface. - Admin API key.
Paste your OpenAI Admin API key (starts withsk-admin).
Click Save to finish.

The new source appears in the Sources list with the Active status. You can now use it in pipelines.

Create an OpenAI pipeline
Once the source is connected, create a pipeline to sync your OpenAI data into your destination.
In the left sidebar, click New pipeline. On the Source step, select OpenAI under Already connected and click Next step.

Choose the OpenAI connection you created earlier and click Next step.

On the Destination step, select your destination (for example, Google BigQuery) and click Next step.

Choose the destination connection you want to load data into and click Next step.

Pipeline configuration
On the final step, choose which OpenAI report to export and how Renta loads it.
Report type and granularity
Pick the report and the size of its time buckets.

-
Report Types Choose one of the nine reports. Each pipeline exports one report into one destination table.
Report type Data Completions Usage Input and output token counts for completions, including cached, text, audio, and image token breakdowns, plus request counts. Embeddings Usage Input token counts and request counts for embeddings. Images Usage Number of generated images and request counts, with image size and source breakdowns. Audio Speeches Usage Characters processed by text-to-speech and request counts. Audio Transcriptions Usage Seconds of transcribed audio and request counts. Moderations Usage Input token counts and request counts for moderations. Vector Stores Usage Vector store storage usage in bytes. Code Interpreter Sessions Usage Number of code interpreter sessions. Cost Report Daily costs in USD broken down by project, user, API key, and line item. -
Granularity Choose the time bucket size: Minute, Hour, or Day. Each row in the destination table is one time bucket for one combination of breakdown values. For
Cost Reportthe only option is Day: the OpenAI costs endpoint supports daily buckets only.
A day contains 1,440 minute buckets, so Minute granularity over a long date range produces a large table and a noticeably longer initial load. For historical analysis, Day is usually enough.
Parameters
Select the fields to include in the destination table. The available set depends on the report type: each report combines breakdown columns, its own metrics, and time bucket fields.

| Name | API name | Description |
|---|---|---|
Project ID text | project_id | Identifier of the project the usage is attributed to. Null when not grouped or not attributable. |
User ID text | user_id | Identifier of the organization user the usage is attributed to. Null when not attributable to a specific user. |
API Key ID text | api_key_id | Identifier of the API key that generated the usage. Null when not attributable to a specific key. |
Model text | model | OpenAI model that produced the usage. For example: gpt-4.1-2025-04-14. |
Batch bool | batch | True when the usage was generated via the Batch API, false otherwise. Null when not grouped by batch. |
Service Tier text | service_tier | Service tier of the requests. For example: default, flex, batch, priority. |
Input Tokens int | input_tokens | The aggregated number of input tokens used, including cached and cache-write tokens (text, audio and image). |
Input Cached Tokens int | input_cached_tokens | The aggregated number of input tokens read from the prompt cache. |
Input Uncached Tokens int | input_uncached_tokens | The aggregated number of input tokens that were not read from the cache. |
Input Cache Write Tokens int | input_cache_write_tokens | The aggregated number of input tokens written to the prompt cache. |
Input Text Tokens int | input_text_tokens | The aggregated number of text input tokens used. |
Input Cached Text Tokens int | input_cached_text_tokens | The aggregated number of text input tokens read from the prompt cache. |
Input Audio Tokens int | input_audio_tokens | The aggregated number of audio input tokens used. |
Input Cached Audio Tokens int | input_cached_audio_tokens | The aggregated number of audio input tokens read from the prompt cache. |
Input Image Tokens int | input_image_tokens | The aggregated number of image input tokens used. |
Input Cached Image Tokens int | input_cached_image_tokens | The aggregated number of image input tokens read from the prompt cache. |
Output Tokens int | output_tokens | The aggregated number of output tokens generated. |
Output Text Tokens int | output_text_tokens | The aggregated number of text output tokens generated. |
Output Audio Tokens int | output_audio_tokens | The aggregated number of audio output tokens generated. |
Output Image Tokens int | output_image_tokens | The aggregated number of image output tokens generated. |
Model Requests int | num_model_requests | The count of requests made to the model. |
Bucket Starting At datetime | bucket_starting_at | Start of the time bucket (UTC, RFC 3339). Bucket size depends on the selected granularity: 1 minute, 1 hour or 1 day. |
Bucket Ending At datetime | bucket_ending_at | End of the time bucket (UTC, RFC 3339, exclusive). |
Bucket Starting Date · Required date | bucket_starting_date | Day-granularity partition key derived from bucket_starting_at. Required — destination tables partition by this column. |
| Name | API name | Description |
|---|---|---|
Project ID text | project_id | Identifier of the project the usage is attributed to. Null when not grouped or not attributable. |
User ID text | user_id | Identifier of the organization user the usage is attributed to. Null when not attributable to a specific user. |
API Key ID text | api_key_id | Identifier of the API key that generated the usage. Null when not attributable to a specific key. |
Model text | model | OpenAI model that produced the usage. For example: gpt-4.1-2025-04-14. |
Input Tokens int | input_tokens | The aggregated number of input tokens used. |
Model Requests int | num_model_requests | The count of requests made to the model. |
Bucket Starting At datetime | bucket_starting_at | Start of the time bucket (UTC, RFC 3339). Bucket size depends on the selected granularity: 1 minute, 1 hour or 1 day. |
Bucket Ending At datetime | bucket_ending_at | End of the time bucket (UTC, RFC 3339, exclusive). |
Bucket Starting Date · Required date | bucket_starting_date | Day-granularity partition key derived from bucket_starting_at. Required — destination tables partition by this column. |
| Name | API name | Description |
|---|---|---|
Project ID text | project_id | Identifier of the project the usage is attributed to. Null when not grouped or not attributable. |
User ID text | user_id | Identifier of the organization user the usage is attributed to. Null when not attributable to a specific user. |
API Key ID text | api_key_id | Identifier of the API key that generated the usage. Null when not attributable to a specific key. |
Model text | model | OpenAI model that produced the usage. For example: gpt-4.1-2025-04-14. |
Size text | size | Image size of the grouped usage result. For example: 1024x1024. Null when not grouped by size. |
Source text | source | Source of the grouped usage result: image.generation, image.edit or image.variation. Null when not grouped by source. |
Images int | images | The number of images processed. |
Model Requests int | num_model_requests | The count of requests made to the model. |
Bucket Starting At datetime | bucket_starting_at | Start of the time bucket (UTC, RFC 3339). Bucket size depends on the selected granularity: 1 minute, 1 hour or 1 day. |
Bucket Ending At datetime | bucket_ending_at | End of the time bucket (UTC, RFC 3339, exclusive). |
Bucket Starting Date · Required date | bucket_starting_date | Day-granularity partition key derived from bucket_starting_at. Required — destination tables partition by this column. |
| Name | API name | Description |
|---|---|---|
Project ID text | project_id | Identifier of the project the usage is attributed to. Null when not grouped or not attributable. |
User ID text | user_id | Identifier of the organization user the usage is attributed to. Null when not attributable to a specific user. |
API Key ID text | api_key_id | Identifier of the API key that generated the usage. Null when not attributable to a specific key. |
Model text | model | OpenAI model that produced the usage. For example: gpt-4.1-2025-04-14. |
Characters int | characters | The number of characters processed. |
Model Requests int | num_model_requests | The count of requests made to the model. |
Bucket Starting At datetime | bucket_starting_at | Start of the time bucket (UTC, RFC 3339). Bucket size depends on the selected granularity: 1 minute, 1 hour or 1 day. |
Bucket Ending At datetime | bucket_ending_at | End of the time bucket (UTC, RFC 3339, exclusive). |
Bucket Starting Date · Required date | bucket_starting_date | Day-granularity partition key derived from bucket_starting_at. Required — destination tables partition by this column. |
| Name | API name | Description |
|---|---|---|
Project ID text | project_id | Identifier of the project the usage is attributed to. Null when not grouped or not attributable. |
User ID text | user_id | Identifier of the organization user the usage is attributed to. Null when not attributable to a specific user. |
API Key ID text | api_key_id | Identifier of the API key that generated the usage. Null when not attributable to a specific key. |
Model text | model | OpenAI model that produced the usage. For example: gpt-4.1-2025-04-14. |
Seconds int | seconds | The number of audio seconds processed. |
Model Requests int | num_model_requests | The count of requests made to the model. |
Bucket Starting At datetime | bucket_starting_at | Start of the time bucket (UTC, RFC 3339). Bucket size depends on the selected granularity: 1 minute, 1 hour or 1 day. |
Bucket Ending At datetime | bucket_ending_at | End of the time bucket (UTC, RFC 3339, exclusive). |
Bucket Starting Date · Required date | bucket_starting_date | Day-granularity partition key derived from bucket_starting_at. Required — destination tables partition by this column. |
| Name | API name | Description |
|---|---|---|
Project ID text | project_id | Identifier of the project the usage is attributed to. Null when not grouped or not attributable. |
User ID text | user_id | Identifier of the organization user the usage is attributed to. Null when not attributable to a specific user. |
API Key ID text | api_key_id | Identifier of the API key that generated the usage. Null when not attributable to a specific key. |
Model text | model | OpenAI model that produced the usage. For example: gpt-4.1-2025-04-14. |
Input Tokens int | input_tokens | The aggregated number of input tokens used. |
Model Requests int | num_model_requests | The count of requests made to the model. |
Bucket Starting At datetime | bucket_starting_at | Start of the time bucket (UTC, RFC 3339). Bucket size depends on the selected granularity: 1 minute, 1 hour or 1 day. |
Bucket Ending At datetime | bucket_ending_at | End of the time bucket (UTC, RFC 3339, exclusive). |
Bucket Starting Date · Required date | bucket_starting_date | Day-granularity partition key derived from bucket_starting_at. Required — destination tables partition by this column. |
| Name | API name | Description |
|---|---|---|
Project ID text | project_id | Identifier of the project the usage is attributed to. Null when not grouped or not attributable. |
Usage Bytes int | usage_bytes | The vector stores usage in bytes. |
Bucket Starting At datetime | bucket_starting_at | Start of the time bucket (UTC, RFC 3339). Bucket size depends on the selected granularity: 1 minute, 1 hour or 1 day. |
Bucket Ending At datetime | bucket_ending_at | End of the time bucket (UTC, RFC 3339, exclusive). |
Bucket Starting Date · Required date | bucket_starting_date | Day-granularity partition key derived from bucket_starting_at. Required — destination tables partition by this column. |
| Name | API name | Description |
|---|---|---|
Project ID text | project_id | Identifier of the project the usage is attributed to. Null when not grouped or not attributable. |
API Key ID text | api_key_id | Identifier of the API key that generated the usage. Null when not attributable to a specific key. |
Sessions int | num_sessions | The number of code interpreter sessions. |
Bucket Starting At datetime | bucket_starting_at | Start of the time bucket (UTC, RFC 3339). Bucket size depends on the selected granularity: 1 minute, 1 hour or 1 day. |
Bucket Ending At datetime | bucket_ending_at | End of the time bucket (UTC, RFC 3339, exclusive). |
Bucket Starting Date · Required date | bucket_starting_date | Day-granularity partition key derived from bucket_starting_at. Required — destination tables partition by this column. |
| Name | API name | Description |
|---|---|---|
Project ID text | project_id | Identifier of the project the cost is attributed to. Null when not attributable to a specific project. |
Project Name text | project_name | Human-readable name of the project. Null when project_id is null. |
Organization ID text | organization_id | Identifier of the OpenAI organization. |
Organization Name text | organization_name | Human-readable name of the OpenAI organization. |
User ID text | user_id | Identifier of the organization user the cost is attributed to. Null when not attributable to a specific user. |
User Email text | user_email | Email of the organization user the cost is attributed to. Null when user_id is null. |
API Key ID text | api_key_id | Identifier of the API key the cost is attributed to. Null when not attributable to a specific key. |
Line Item text | line_item | Human-readable description of the cost line item. For example: gpt-4.1-2025-04-14, input. |
Amount Value decimal | amount_value | Cost amount as a decimal value. Flattened from amount.value. |
Amount Currency text | amount_currency | Currency of the amount. Lowercase ISO code, always usd. Flattened from amount.currency. |
Quantity decimal | quantity | Number of priced units the line item covers (e.g. tokens). May be 0 for zero-cost lines. |
Bucket Starting At datetime | bucket_starting_at | Start of the daily time bucket (UTC, RFC 3339). |
Bucket Ending At datetime | bucket_ending_at | End of the daily time bucket (UTC, RFC 3339, exclusive). |
Bucket Starting Date · Required date | bucket_starting_date | Day-granularity partition key derived from bucket_starting_at. Required — destination tables partition by this column. |
Tick the fields you need or click Select All. Destination column names follow the API names under each field: Project ID becomes project_id.
Every report also includes three time fields: Bucket Starting At and Bucket Ending At (bucket boundaries in UTC) and Bucket Starting Date, the day-level date column the destination table is partitioned by. Bucket Starting Date is pre-selected and cannot be removed.
Breakdown columns can be null: the OpenAI API omits the attribution when usage cannot be tied to a specific project, user, or API key. The totals in such rows are still correct.
Table name and date range
Name the pipeline and set the historical period to load.

- Integration name.
The name of the pipeline. It is used exclusively in the Renta interface. - Table name.
The destination table name. You can keep the auto-generated name or enter your own.

- Date start.
The first date of the extraction period. - Date end.
The last date of the extraction period. Leave it as Today to keep collecting new data on every run.
Overwrite period
The overwrite period defines how many recent days Renta reloads on every run.

On each run, Renta re-fetches the report starting from the date of the last successful run minus the overwrite period. The affected days are deleted from the destination table and inserted again, while older data stays untouched. The default is Last 1 day.
Schedule
Choose how often the pipeline runs.

| Schedule type | Description |
|---|---|
| Manual | The pipeline runs only when triggered manually through the interface or via API. |
| Daily | The pipeline runs once a day at the specified update time. |
| Interval | The pipeline runs at specified time intervals. |
| Cron Expression | The pipeline runs on a schedule defined by a cron expression. |
For Daily schedules, set the Update time, the exact time each run starts, then click Create pipeline.

Renta also supports API triggers and integration with external orchestrators such as Apache Airflow, Dagster, and Prefect. See the full scheduling documentation for details.
The new pipeline appears in the Pipelines section under the ETL tab, where you can track its runs, progress, and the destination table name.

Sync strategy
All OpenAI reports are time-bucketed statistics, so they share one synchronization strategy.
| Strategy | Supported report types | Description |
|---|---|---|
| Incremental | Completions Usage, Embeddings Usage, Images Usage, Audio Speeches Usage, Audio Transcriptions Usage, Moderations Usage, Vector Stores Usage, Code Interpreter Sessions Usage, Cost Report | Each destination table is partitioned by the bucket_starting_date column. On every run Renta reloads the window from the last successful run minus the overwrite period to the end of the date range: those daily partitions are deleted and inserted again, and older partitions stay untouched. |
Changing the selected parameters updates the table schema, so the next run after the change reloads the entire date range.
Ready to get started?
Build your data pipeline today or get a personalized demo. Start free!
Need help?
Get expert support to ensure your project succeeds. We're here to help!
Feature requests?
Help shape our product! Share your ideas for new features and integrations.