- Keeping up with AI
- Posts
- How to build your own OpenAI cost calculator
How to build your own OpenAI cost calculator
Includes Python code
How to build your own OpenAI cost calculator
We now have our own domain where new posts are being published. Subscribe us there.
tl;dr
This post covers 2 network calls made on platform.openai.com .
The first network call gives the subscription details and can be made using an
OPENAI_API_TOKEN
The second network call gives the cost details for a particular period and can be made using an
OPENAI_API_TOKEN
There is a curl call, python code, and a bonus curl call for Credit grant details (but it only works from the browser)
In this post, we will learn how you can build your own OpenAI cost calculator.
OpenAI Subscription Details
I discovered a subscription
network call from the Network tab of Chrome Dev tools.
There is a call being made to the subscription endpoint. Here is a curl.
curl 'https://api.openai.com/dashboard/billing/subscription'
-H 'authority: api.openai.com'
-H 'accept: */*'
-H 'accept-language: en-GB,en-US;q=0.9,en;q=0.8'
-H 'authorization: Bearer sess-${SESSION_ID}'
-H 'openai-organization: org-${ORG_ID}'
-H 'origin: https://platform.openai.com'
-H 'referer: https://platform.openai.com/'
-H 'sec-fetch-dest: empty'
-H 'sec-fetch-mode: cors'
-H 'sec-fetch-site: same-site'
-H 'sec-gpc: 1'
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36'
--compressed
and here is the response from the above curl
{
"object": "billing_subscription",
"has_payment_method": true,
"canceled": false,
"canceled_at": null,
"delinquent": null,
"access_until": 1685249945,
"soft_limit": 1000000,
"hard_limit": 2000000,
"system_hard_limit": 2000000,
"soft_limit_usd": 100.0,
"hard_limit_usd": 120.0,
"system_hard_limit_usd": 120.0,
"plan": {
"title": "Pay-as-you-go",
"id": "payg"
},
"account_name": null,
"po_number": null,
"billing_email": null,
"tax_ids": null,
"billing_address": {
"city": "city_name",
"line1": "address line 1",
"line2": "address line 2",
"state": "state",
"country": "IN",
"postal_code": "111111"
},
"business_address": null
}
Note the session sess-{session_id}
in the curl call is obtained from the login call. This is a bit complicated process where in you first have to make the login call and then get the session id. Also, high chance that your login call won’t get the correct response because of the bot prevention mechanism applied.
I started playing around and the first thing that I did was replacing sess-{session_id}
with my OPENAI_API_KEY
. And it worked like magic!
So, here is the subscription call curl with OPENAI_API_KEY
(eg: sk-
)
curl 'https://api.openai.com/dashboard/billing/subscription'
-H 'authority: api.openai.com'
-H 'accept: */*'
-H 'accept-language: en-GB,en-US;q=0.9,en;q=0.8'
-H 'authorization: Bearer ${OPENAI_API_KEY}'
-H 'openai-organization: org-${ORG_ID}'
-H 'origin: https://platform.openai.com'
-H 'referer: https://platform.openai.com/'
-H 'sec-fetch-dest: empty'
-H 'sec-fetch-mode: cors'
-H 'sec-fetch-site: same-site'
-H 'sec-gpc: 1'
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36'
--compressed
The response for this curl call is the same.
The subscription call is useful to get billing limits(soft and hard), plan details, and billing account details and addresses.
Python code to get subscription details
Here is a Python function that you can call from your app. You just need to pass the OPENAI_API_TOKEN
. ORG_ID
is optional
import requests
def get_openai_subscription_details(api_key, org_id=None):
'''
Get subscription details from OpenAI
'''
headers = {
'authority': 'api.openai.com',
'accept': '*/*',
'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8',
'authorization': f'Bearer {api_key}',
'origin': 'https://platform.openai.com',
'referer': 'https://platform.openai.com/',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'sec-gpc': '1',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36',
}
if org_id:
headers['openai-organization'] = f'org-{org_id}'
response = requests.get('https://api.openai.com/dashboard/billing/subscription', headers=headers)
return response.json()
OPENAI_API_KEY = '' # set the one for which you want to calculate cost
print(get_openai_subscription_details(OPENAI_API_KEY))
OpenAI Cost Details
But how do I get the cost that I have spent so far?
So I went to the Usage tab, where OpenAI shows a graph and tabular view of all the API calls being made, usage, and credit details. From this tab, I discovered an usage
endpoint. This is exactly what we need to build the OpenAI cost calculator.
Here is the curl call:
curl 'https://api.openai.com/dashboard/billing/usage?end_date=2023-06-01&start_date=2023-05-01'
-H 'authority: api.openai.com'
-H 'accept: */*'
-H 'accept-language: en-GB,en-US;q=0.9,en;q=0.8'
-H 'authorization: Bearer ${OPENAI_API_KEY}'
-H 'openai-organization: org-${ORG_ID}'
-H 'origin: https://platform.openai.com'
-H 'referer: https://platform.openai.com/'
-H 'sec-fetch-dest: empty'
-H 'sec-fetch-mode: cors'
-H 'sec-fetch-site: same-site'
-H 'sec-gpc: 1'
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36'
--compressed
and the response from the above call
{
"object": "list",
"daily_costs": [
{
"timestamp": 1682899200.0,
"line_items": [
{
"name": "Instruct models",
"cost": 0.00144
},
{
"name": "Chat models",
"cost": 26.369
},
{
"name": "GPT-4",
"cost": 111.978
},
{
"name": "Fine-tuned models",
"cost": 0.0
},
{
"name": "Embedding models",
"cost": 0.0002
},
{
"name": "Image models",
"cost": 0.0
},
{
"name": "Audio models",
"cost": 0.0
}
]
},
{
"timestamp": 1685145600.0,
"line_items": [
{
"name": "Instruct models",
"cost": 0.0
},
{
"name": "Chat models",
"cost": 0.0144
},
{
"name": "GPT-4",
"cost": 0.0
},
{
"name": "Fine-tuned models",
"cost": 0.0
},
{
"name": "Embedding models",
"cost": 0.0
},
{
"name": "Image models",
"cost": 0.0
},
{
"name": "Audio models",
"cost": 0.0
}
]
}
],
"total_usage": 649.65
}
The response has a daily_costs
object where each object contains a timestamp for the day and then the individual cost for each model like
Instruct models
Chat models
GPT-4
Fine-tuned models
Embedding models
Image models
Audio models.
You can use this API call to get the total cost for any period. If you want the cost from the start, you can keep start_date
as 2020-06-11
(the date when GPT-3 was launched)
The best part here is that this API call works at the token level, so you can use this to calculate cost at a token level. You can create multiple tokens for various apps or clients and then maintain a limit at your end for each token. This is something that is totally missing in OpenAI’s current platform.
Python code to get cost details
Here is a Python function that you can call from your app. You just need to pass the OPENAI_API_KEY
, start_date
and end_date
. ORG_ID
is optional.
def get_openai_cost_details(api_key, start_date, end_date, org_id=None):
'''
Get cost details from OpenAI.
start_date and end_date format: 2023-05-28
'''
headers = {
'authority': 'api.openai.com',
'accept': '*/*',
'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8',
'authorization': f'Bearer {api_key}',
'origin': 'https://platform.openai.com',
'referer': 'https://platform.openai.com/',
'sec-fetch-dest': 'empty',
'sec-fetch-mode': 'cors',
'sec-fetch-site': 'same-site',
'sec-gpc': '1',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36',
}
if org_id:
headers['openai-organization'] = f'org-{org_id}'
params = {
'end_date': end_date,
'start_date': start_date
}
response = requests.get(
'https://api.openai.com/dashboard/billing/usage',
params=params,
headers=headers
)
return response.json()
OPENAI_API_KEY = '' # set the one for which you want to calculate cost
print(get_openai_cost_details(OPENAI_API_KEY, '2023-05-01', '2023-06-01'))
OpenAI Grant Details
There is another API call to credit_grants
the endpoint. It gives the detail of how many credits have been used. Here is the curl call
curl 'https://api.openai.com/dashboard/billing/credit_grants>'
-H 'authority: api.openai.com'
-H 'accept: */*'
-H 'accept-language: en-GB,en-US;q=0.9,en;q=0.8'
-H 'authorization: Bearer ${OPENAI_SESSION_KEY}'
-H 'openai-organization: org-${ORG_ID}'
-H 'origin: https://platform.openai.com'
-H 'referer: https://platform.openai.com/'
-H 'sec-fetch-dest: empty'
-H 'sec-fetch-mode: cors'
-H 'sec-fetch-site: same-site'
-H 'sec-gpc: 1'
-H 'user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.53 Safari/537.36'
--compressed
and here is the response
{
"object": "credit_summary",
"total_granted": 100.0,
"total_used": 100,
"total_available": 0,
"grants": {
"object": "list",
"data": [
{
"object": "credit_grant",
"id": "",
"grant_amount": 100.0,
"used_amount": 100.0,
"effective_at": 1685249945.0,
"expires_at": 1685249945.0
}
]
}
}
Note that this API call can be made using session_key
only. I tried the above curl OPENAI_API_KEY
and got the following error:
{'error': {'message': 'Your request to GET /dashboard/billing/credit_grants must be made with a session key (that is, it can only be made from the browser). You made it with the following key type: secret.', 'type': 'server_error', 'param': None, 'code': None}}
If you really want to get the credit details, you will have to first get the session key using a login call.
Few things to note
The endpoints listed above are internal endpoints and may change from time to time. I remember the
subscription
andbilling
endpoint use to takeOPENAI_API_KEY
some time back. Now it’s takingOPENAI_SESSION_KEY
. So they can be changed or removed without any prior notice.Please note that the content, findings, interpretations, and conclusions expressed in this document are solely my own and do not reflect the views or policies of OpenAI. This document is intended for informational purposes only and should not be considered as an official statement or endorsement from OpenAI.