Use this guide to manage an existing project rate limit and create a monthly spend alert. Rate limits constrain a project’s model usage over time. Spend alerts notify your team when monthly usage reaches a threshold, but they don’t stop API requests or enforce a spending cap.
After completing the main workflow, you will have a repeatable configuration that:
- Reads the rate-limit records available to an existing project.
- Manages the request and token limits for one model.
- Sends an email alert when the project’s monthly spend reaches a threshold.
Before you begin
Complete the Terraform provider setup and export an Admin API key as OPENAI_ADMIN_KEY. You also need:
- The ID of an existing project.
- At least one email address that should receive spend alerts.
Use a test project when evaluating the workflow. You will identify the rate-limit record for a text model in the next section. OpenAI creates the rate-limit records available to a project; Terraform updates those records rather than creating new ones.
Discover project rate limits
Read the rate-limit records available to a project:
1
2
3
4
5
6
7
data "openai_project_rate_limits" "current" {
project_id = "proj_123"
}
output "project_rate_limits" {
value = data.openai_project_rate_limits.current.rate_limits
}The data source makes a read-only request:
project_idselects the project to inspect.rate_limitscontains one object for each available model rate limit, including itsid,model, and applicable limit values.- The output makes the records visible after
terraform planorterraform apply.
Use the record whose model matches the model you want to control. Copy its id; the next resource uses that value as rate_limit_id. Keep the ID as an explicit input to prevent a provider or API change from selecting a different record.
Manage an existing rate limit
Manage the request and token limits for the selected text-model record:
1
2
3
4
5
6
resource "openai_project_rate_limit" "application" {
project_id = "proj_123"
rate_limit_id = "rl-gpt-3.5-turbo"
max_requests_per_1_minute = 500
max_tokens_per_1_minute = 200000
}Each argument has a specific role:
project_ididentifies the project whose rate limit will change.rate_limit_ididentifies an existing model rate-limit record. It isn’t a model ID.max_requests_per_1_minutelimits the number of requests the project can send for that model each minute.max_tokens_per_1_minutelimits the number of tokens the project can process for that model each minute.
Set only the fields that apply to the selected record. Other record types can expose limits for images per minute, audio megabytes per minute, requests per day, or Batch input tokens per day. A configured value can’t exceed the limit available to the organization and project.
Although the first Terraform plan shows this resource as an addition, the provider updates the existing rate-limit record and then stores it in Terraform state. Changing a configured limit sends another update.
Removing openai_project_rate_limit from the configuration removes the record
from Terraform state, but it doesn’t reset or delete the remote rate limit.
Set the desired remote values before removing the resource if another workflow
will manage the record.
Configure a project spend alert
Create a monthly project spend alert:
1
2
3
4
5
6
7
8
9
resource "openai_project_spend_alert" "monthly" {
project_id = "proj_123"
threshold_amount = 20000
currency = "USD"
interval = "month"
notification_channel_type = "email"
notification_channel_recipients = ["platform-alerts@example.com"]
notification_channel_subject_prefix = "OpenAI project spend"
}The alert definition combines the spend condition and its notification channel:
project_idlimits the alert to spend from one project.threshold_amountis the monthly threshold in cents.20000represents USD 200.currencymust beUSD.intervalmust bemonth.notification_channel_typemust beemail.notification_channel_recipientsmust contain at least one recipient.notification_channel_subject_prefixis optional text added to alert email subjects.
Terraform creates the alert and stores its generated alert_id. Changing the threshold or notification fields updates the alert. Removing the resource deletes the remote alert.
Spend alerts are notifications, not hard limits. Define an incident or administrative response for each threshold, and use rate limits to constrain request volume independently.
Configure an organization spend alert
Use an organization alert when the threshold should cover spend across the organization:
1
2
3
4
5
6
7
resource "openai_organization_spend_alert" "monthly" {
threshold_amount = 100000
currency = "USD"
interval = "month"
notification_channel_type = "email"
notification_channel_recipients = ["platform-alerts@example.com"]
}This resource uses the same threshold units, interval, currency, and notification fields as a project alert. It doesn’t take a project_id because it measures organization-wide spend. The example sends an email after monthly organization spend reaches USD 1,000.
You can manage project and organization alerts together. Use distinct thresholds and recipients when different teams own the response at each scope.
Run the complete example
The focused examples use concrete values to explain each resource. The complete configuration replaces environment-specific values with variables and combines project rate-limit discovery, one managed rate limit, and one project spend alert.
Save the following configuration as main.tf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
terraform {
required_version = ">= 1.0"
required_providers {
openai = {
source = "openai/openai"
version = ">= 1.0.0"
}
}
}
provider "openai" {}
variable "project_id" {
type = string
}
variable "rate_limit_id" {
type = string
description = "Existing rate-limit record for the text model to manage."
}
variable "max_requests_per_minute" {
type = number
}
variable "max_tokens_per_minute" {
type = number
}
variable "project_spend_threshold_cents" {
type = number
description = "Monthly project spend threshold in cents."
validation {
condition = var.project_spend_threshold_cents > 0
error_message = "The project spend threshold must be greater than zero."
}
}
variable "alert_recipients" {
type = list(string)
validation {
condition = length(var.alert_recipients) > 0
error_message = "Provide at least one spend-alert recipient."
}
}
data "openai_project_rate_limits" "current" {
project_id = var.project_id
}
resource "openai_project_rate_limit" "application" {
project_id = var.project_id
rate_limit_id = var.rate_limit_id
max_requests_per_1_minute = var.max_requests_per_minute
max_tokens_per_1_minute = var.max_tokens_per_minute
}
resource "openai_project_spend_alert" "monthly" {
project_id = var.project_id
threshold_amount = var.project_spend_threshold_cents
currency = "USD"
interval = "month"
notification_channel_type = "email"
notification_channel_recipients = var.alert_recipients
notification_channel_subject_prefix = "OpenAI project spend"
}
output "available_rate_limits" {
value = data.openai_project_rate_limits.current.rate_limits
}
output "managed_rate_limit_model" {
value = openai_project_rate_limit.application.model
}
output "project_spend_alert_id" {
value = openai_project_spend_alert.monthly.alert_id
}Create terraform.tfvars with an existing project ID, the rate-limit record ID you discovered for a text model, approved limits, a threshold in cents, and the alert recipients:
1
2
3
4
5
6
7
8
project_id = "proj_123"
rate_limit_id = "rl-gpt-3.5-turbo"
max_requests_per_minute = 500
max_tokens_per_minute = 200000
project_spend_threshold_cents = 20000
alert_recipients = ["platform-alerts@example.com"]Choose request and token values that don’t exceed the limits currently available to the project. The available_rate_limits output in the plan shows the current records and values for comparison.
Initialize Terraform, then review and apply a saved plan:
1
2
3
4
5
6
terraform init
terraform fmt
terraform validate
terraform plan -out=tfplan
terraform show tfplan
terraform apply tfplanThe first plan should contain two resources to add. Terraform describes the rate-limit resource as an addition to state, but applying it updates the existing OpenAI rate-limit record. The other addition creates the project spend alert. After the apply, terraform output prints the available rate limits, the model associated with the managed record, and the alert ID.
Run terraform plan again to confirm that the configuration produces no further changes. If it shows drift, determine whether another administrator or automation changed the rate limit or spend alert before applying another update.