The API endpoint is most certainly missing or down. The Status 404 doesn’t even return a body error message.
httpx.HTTPStatusError: Client error '404 Not Found' for url 'https://api.openai.com/v1/organization/costs?start_time=1761350400'
Here’s a Python script distilled down, and where the function having “debug:True” sends only the required start date parameter (and I have API usage costs to return and tried 180 days, so 404 should not be ‘no results’).
'''OpenAI admin framework – costs endpoint example
Environment:
export OPENAI_ADMIN_KEY=... # required “sk‑admin‑…” key
export OPENAI_ORG_ID=... # optional
export OPENAI_PROJECT_ID=... # optional
Dependencies:
pip install httpx
'''
from __future__ import annotations
import argparse
import json
import logging
import os
from datetime import UTC, datetime, timedelta
from typing import Any, Dict, Tuple
import httpx
logger = logging.getLogger(__name__)
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
def get_auth_headers() -> Dict[str, str]:
"""Return standard admin headers plus JSON content negotiation."""
api_key = os.getenv("OPENAI_ADMIN_KEY")
if not api_key:
raise ValueError("Set OPENAI_ADMIN_KEY first (must be an *admin* key).")
headers: Dict[str, str] = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json", # debug: send this simply because OpenAI CURL has it
"Accept": "application/json",
}
org_id = os.getenv("OPENAI_ORG_ID")
project_id = os.getenv("OPENAI_PROJECT_ID")
if org_id:
headers["OpenAI-Organization"] = org_id
if project_id:
headers["OpenAI-Project"] = project_id # unknown if useful (or breaking)
return headers
def admin_get(
path: str,
*,
params: Dict[str, Any] | None = None,
timeout: float = 30.0,
) -> Tuple[httpx.Response, Dict[str, str]]:
"""GET wrapper for query-only OpenAI endpoints (no body/JSON)"""
try:
resp = httpx.get(
f"https://api.openai.com{path}",
headers=get_auth_headers(),
params=params,
timeout=timeout,
)
hdrs = dict(resp.headers)
resp.raise_for_status()
return resp, hdrs
except httpx.HTTPStatusError as err:
body_text = err.response.text.strip() or "<no body>"
print(f"[Admin API] HTTP {err.response.status_code}: {body_text}", flush=True)
logger.error("HTTP %s: %s", err.response.status_code, body_text)
raise
except httpx.RequestError as err:
logger.error("Request error: %s", err)
raise
# ---------------------------------------------------------------------------
# Costs endpoint
# ---------------------------------------------------------------------------
def get_costs(
past_days: int = 14,
*,
debug: bool = True,
) -> Dict[str, Any]:
"""
Retrieve organisation‑level cost buckets.
Parameters
----------
past_days
Number of 24‑hour buckets (1 – 180).
debug
• True → send **only** the required `start_time`.
• False → include `end_time`, `limit`, `bucket_width`, & `group_by`.
"""
past_days = max(1, min(past_days, 180))
now = datetime.now(tz=UTC)
start_dt = (now - timedelta(days=past_days)).replace(
hour=0, minute=0, second=0, microsecond=0
)
params: Dict[str, Any] = {"start_time": int(start_dt.timestamp())}
if not debug:
params.update(
{
"end_time": int(now.timestamp()),
"limit": past_days,
"bucket_width": "1d",
"group_by": ["line_item"],
}
)
resp, _ = admin_get("/v1/organization/costs", params=params)
return resp.json()
# ---------------------------------------------------------------------------
# CLI
# ---------------------------------------------------------------------------
def main() -> None:
parser = argparse.ArgumentParser("Fetch OpenAI organisation cost data")
parser.add_argument("--days", type=int, default=14,
help="How many 24‑hour buckets (1‑180, default 14)")
parser.add_argument("--full", action="store_true",
help="Send the full parameter set (turns off debug)")
args = parser.parse_args()
costs = get_costs(args.days, debug=not args.full)
print(json.dumps(costs, indent=2, sort_keys=True))
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
main()
Verified parameters against the API’s OpenAPI specification.