Developer Dashboard

User API Reference

The User API provides programmatic access to your account information, credit balance, and transaction history. Use these endpoints to monitor usage, track spending, and retrieve precise cost data for API calls.

Base URL

https://api.avalai.ir/user/v1

Overview

The User API enables you to:

  • Monitor credit usage - Check remaining balance and credit sources
  • Track API usage - List and filter transactions with flexible parameters
  • Analyze spending - Get aggregated statistics grouped by model, provider, day, or API key
  • Lookup transactions - Retrieve specific transactions by request ID for precise cost data

Data Retention

Important

Transaction records are guaranteed to be accessible for at least 90 days. There is no guarantee that transaction data will be available after 3 months. If you need to retain cost data for longer periods, please store the transaction details in your own database.

Key Features

FeatureDescription
Real-time credit dataCredit information is always up-to-date
Flexible filteringFilter transactions by model, provider, date range, and more
Aggregated statisticsGet summary data grouped by day, model, provider, or API key
Batch lookupsRetrieve up to 1000 transactions in a single request
Precise cost trackingGet exact cost breakdown for any API request via request ID
90-day retentionTransaction records are accessible for at least 90 days

Authentication

All User API endpoints require Bearer token authentication using your AvalAI API key.

bash
# Set your API key
export AVALAI_API_KEY="your-avalai-api-key"

# Example request
curl -X GET "https://api.avalai.ir/user/v1/credit" \
  -H "Authorization: Bearer $AVALAI_API_KEY"
python
from openai import OpenAI
import requests

# Using requests for User API
api_key = "your-avalai-api-key"
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}

response = requests.get("https://api.avalai.ir/user/v1/credit", headers=headers)
print(response.json())
javascript
const apiKey = process.env.AVALAI_API_KEY;

const response = await fetch("https://api.avalai.ir/user/v1/credit", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
});

const data = await response.json();
console.log(data);
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	apiKey := os.Getenv("AVALAI_API_KEY")

	req, _ := http.NewRequest("GET", "https://api.avalai.ir/user/v1/credit", nil)
	req.Header.Set("Authorization", "Bearer "+apiKey)
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
php
<?php
$apiKey = getenv('AVALAI_API_KEY');

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.avalai.ir/user/v1/credit');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $apiKey,
    'Content-Type: application/json'
]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
print_r($data);
?>

Authentication Errors

Status CodeErrorDescription
401unauthorizedMissing or invalid API key
403forbiddenAccount is suspended or inactive

Rate Limiting

The /user/v1 endpoints apply per-user rate limiting based on your account tier.

/user/v1 Rate Limits by Tier

Account TierRequest Limit
Basic (Tier 0)3 requests per minute
Tier 115 requests per minute
Tier 250 requests per minute
Tier 3150 requests per minute
Tier 4350 requests per minute
Tier 5750 requests per minute

Rate Limit Headers

Every response includes rate limit information:

HeaderDescription
x-ratelimit-limit-requestsMaximum requests per minute
x-ratelimit-remaining-requestsRemaining requests in current window
x-ratelimit-reset-requestsSeconds until the rate limit resets

Rate Limit Exceeded Response

json
{
  "error": "rate_limit_exceeded",
  "message": "Rate limit exceeded. Try again in 45 seconds."
}

Endpoints

GET /credit

Get your current credit balance, limits, and credit sources.

URL: GET https://api.avalai.ir/user/v1/credit

Request

bash
curl -X GET "https://api.avalai.ir/user/v1/credit" \
  -H "Authorization: Bearer $AVALAI_API_KEY"
python
import requests

api_key = "your-avalai-api-key"
headers = {"Authorization": f"Bearer {api_key}"}

response = requests.get("https://api.avalai.ir/user/v1/credit", headers=headers)
credit_info = response.json()
print(f"Remaining credit: {credit_info['remaining_irt']} IRT")
print(f"Account tier: {credit_info['account_tier']}")
javascript
const response = await fetch("https://api.avalai.ir/user/v1/credit", {
  headers: { Authorization: `Bearer ${process.env.AVALAI_API_KEY}` },
});

const creditInfo = await response.json();
console.log(`Remaining credit: ${creditInfo.remaining_irt} IRT`);
console.log(`Account tier: ${creditInfo.account_tier}`);
go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
)

type CreditResponse struct {
	Limit        float64 `json:"limit"`
	RemainingIRT float64 `json:"remaining_irt"`
	AccountTier  int     `json:"account_tier"`
}

func main() {
	req, _ := http.NewRequest("GET", "https://api.avalai.ir/user/v1/credit", nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AVALAI_API_KEY"))

	resp, _ := (&http.Client{}).Do(req)
	defer resp.Body.Close()

	var credit CreditResponse
	json.NewDecoder(resp.Body).Decode(&credit)
	fmt.Printf("Remaining credit: %.2f IRT\n", credit.RemainingIRT)
}
php
<?php
$apiKey = getenv('AVALAI_API_KEY');

$ch = curl_init('https://api.avalai.ir/user/v1/credit');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $apiKey]);

$response = curl_exec($ch);
curl_close($ch);

$credit = json_decode($response, true);
echo "Remaining credit: " . $credit['remaining_irt'] . " IRT\n";
echo "Account tier: " . $credit['account_tier'] . "\n";
?>

Response

json
{
  "limit": 0.0,
  "remaining_irt": 742927.85,
  "remaining_unit": 0.0,
  "total_unit": 6.44622863340564,
  "exchange_rate": 115250,
  "account_tier": 5,
  "credit_sources": {
    "grants": [],
    "packages": [
      {
        "id": "25",
        "template_id": "d-o3050s",
        "name": "مدل‌های زبانی منتخب OpenAI روزانه پایه",
        "description": "٪۴۰ تخفیف در مدل‌های منتخب OpenAI",
        "amount_irt": "500000.00",
        "remaining_irt": "498447.15",
        "end_date": "2025-11-27T15:05:07.404882+00:00",
        "allowed_services": [
          "api"
        ],
        "scope_details": {
          "api": [
            "gpt-5-chat",
            "gpt-5-mini",
            "gpt-5.6-luna",
            "gpt-5.4-mini",
            "o4-mini",
            "o3-mini"
          ]
        }
      }
    ]
  }
}

Response Fields

FieldTypeDescription
limitfloatTotal credit limit in IRT
remaining_irtfloatRemaining credit in IRT
remaining_unitfloatRemaining credit in units (USD)
total_unitfloatTotal credit in units
exchange_rateintCurrent IRT to unit (USD) exchange rate
account_tierintAccount tier (0-5), affects rate limits
credit_sourcesobjectBreakdown of credit sources
credit_sources.grantsarrayActive grants
credit_sources.packagesarrayActive packages

Credit Source Fields

Grant:

FieldTypeDescription
idstringUnique grant identifier
descriptionstringGrant description
amount_irtstringTotal grant amount in IRT
remaining_irtstringRemaining amount in IRT
end_datestringExpiration date (ISO 8601)
allowed_servicesarrayServices this grant can be used for
scope_detailsobjectModel/provider restrictions

Package:

FieldTypeDescription
idstringUnique package identifier
template_idstringPackage template ID
namestringPackage name
descriptionstringPackage description
amount_irtstringTotal package amount in IRT
remaining_irtstringRemaining amount in IRT
end_datestringExpiration date (ISO 8601)
allowed_servicesarrayServices this package can be used for
scope_detailsobjectModel/provider restrictions

GET /transactions

Get a paginated list of your API transactions.

URL: GET https://api.avalai.ir/user/v1/transactions

Query Parameters

ParameterTypeDefaultDescription
hours_agoint24Hours to look back (1-720). Ignored if dates provided.
start_datestring-Start date (YYYY-MM-DD). Requires end_date.
end_datestring-End date (YYYY-MM-DD). Requires start_date.
pageint1Page number (1-10000)
page_sizeint100Items per page (1-1000)
safety_identifierstring-Filter by your internal identifier
api_key_idint-Filter by specific API key ID
modelstring-Filter by model name (partial match)
providerstring-Filter by provider name
status_codeint-Filter by HTTP status code

Examples

bash
# Last 24 hours (default)
curl -X GET "https://api.avalai.ir/user/v1/transactions" \
  -H "Authorization: Bearer $AVALAI_API_KEY"

# Last 7 days
curl -X GET "https://api.avalai.ir/user/v1/transactions?hours_ago=168" \
  -H "Authorization: Bearer $AVALAI_API_KEY"

# Specific date range
curl -X GET "https://api.avalai.ir/user/v1/transactions?start_date=2025-01-01&end_date=2025-01-07" \
  -H "Authorization: Bearer $AVALAI_API_KEY"

# Filter by model
curl -X GET "https://api.avalai.ir/user/v1/transactions?model=gpt-5.5&page_size=50" \
  -H "Authorization: Bearer $AVALAI_API_KEY"
python
import requests

api_key = "your-avalai-api-key"
headers = {"Authorization": f"Bearer {api_key}"}

# Last 24 hours (default)
response = requests.get("https://api.avalai.ir/user/v1/transactions", headers=headers)

# With filters
response = requests.get(
    "https://api.avalai.ir/user/v1/transactions",
    headers=headers,
    params={"model": "gpt-5.6-luna", "hours_ago": 168, "page_size": 50},  # Last 7 days
)

transactions = response.json()
for tx in transactions["transactions"]:
    print(f"{tx['id']}: {tx['model']} - {tx['tokens']['total']} tokens")
javascript
const apiKey = process.env.AVALAI_API_KEY;

// With filters
const params = new URLSearchParams({
  model: "gpt-5.6-luna",
  hours_ago: "168",
  page_size: "50",
});

const response = await fetch(
  `https://api.avalai.ir/user/v1/transactions?${params}`,
  {
    headers: { Authorization: `Bearer ${apiKey}` },
  },
);

const data = await response.json();
data.transactions.forEach((tx) => {
  console.log(`${tx.id}: ${tx.model} - ${tx.tokens.total} tokens`);
});
go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"os"
)

func main() {
	baseURL := "https://api.avalai.ir/user/v1/transactions"
	params := url.Values{}
	params.Add("model", "gpt-5.6-luna")
	params.Add("hours_ago", "168")
	params.Add("page_size", "50")

	req, _ := http.NewRequest("GET", baseURL+"?"+params.Encode(), nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AVALAI_API_KEY"))

	resp, _ := (&http.Client{}).Do(req)
	defer resp.Body.Close()

	var result map[string]interface{}
	json.NewDecoder(resp.Body).Decode(&result)
	fmt.Printf("Total transactions: %v\n", result["total"])
}
php
<?php
$apiKey = getenv('AVALAI_API_KEY');

$params = http_build_query([
    'model' => 'gpt-5.6-luna',
    'hours_ago' => 168,
    'page_size' => 50
]);

$ch = curl_init('https://api.avalai.ir/user/v1/transactions?' . $params);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $apiKey]);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);
foreach ($data['transactions'] as $tx) {
    echo $tx['id'] . ': ' . $tx['model'] . ' - ' . $tx['tokens']['total'] . " tokens\n";
}
?>

Response

json
{
  "transactions": [
    {
      "id": "019ac1c0-9ff3-7663-b0b9-fbcf2461939a",
      "created_at": "2025-11-26T20:06:23.442Z",
      "requested_at": "2025-11-26T20:00:18.031Z",
      "safety_identifier": null,
      "model": "gpt-5.4-mini",
      "provider": "openai",
      "status_code": 200,
      "stream": false,
      "tokens": {
        "total": 30,
        "prompt": 10,
        "completion": 20,
        "reasoning": 0,
        "cached": 0
      }
    }
  ],
  "total": 100,
  "page": 1,
  "page_size": 100,
  "has_more": false
}

Transaction Fields

FieldTypeDescription
idstringUnique transaction identifier (UUID v7) - same as avalai-request-id header
created_atstringTransaction cost processing time - when the transaction was processed and its cost was calculated (ISO 8601)
requested_atstringRequest initiation time (ISO 8601)
modelstringModel used (e.g., "gpt-5.4")
providerstringProvider name (e.g., "openai", "anthropic")
status_codeintHTTP response status code
streamboolWhether request used streaming
tokens.totalintTotal tokens used
tokens.promptintPrompt tokens
tokens.completionintCompletion tokens
tokens.reasoningintReasoning tokens (o1/o3 models)
tokens.cachedintCached tokens (prompt caching)
safety_identifierstringYour internal identifier (if provided)

POST /transactions/lookup

Lookup specific transactions by their UUIDs. This is the key endpoint for precise cost tracking - use the avalai-request-id from API response headers to get exact cost details.

URL: POST https://api.avalai.ir/user/v1/transactions/lookup

Important for Resellers: This endpoint returns the exact cost of any API request, which is 100% accurate and available within 30 seconds of the request completing. See the Reseller Cost Tracking Guide for a complete workflow.

Retrieving Request ID from SDKs

When using official SDKs like the OpenAI Python SDK, the avalai-request-id header is automatically captured and made available through the response object. Here's how to access it in different SDKs:

Python (OpenAI SDK)

python
from openai import OpenAI

client = OpenAI(
    api_key="your-avalai-api-key",
    base_url="https://api.avalai.ir/v1",
)

response = client.chat.completions.create(
    model="gpt-5.4-mini",
    messages=[{"role": "user", "content": "Hello!"}],
)

# Access the request ID from the response object
request_id = response._request_id
print(f"Request ID: {request_id}")

# You can now use this request_id to lookup the transaction cost
Responses API version

Use this version when the selected model supports /v1/responses. messages moves to input, and the final text is read from response.output_text.

python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["AVALAI_API_KEY"],
    base_url="https://api.avalai.ir/v1",
)

response = client.responses.create(
    model="gpt-5.4-mini",
    instructions="You are a helpful assistant.",
    input="Hello!",
)

print(response.output_text)
  • messagesinput
  • system message → instructions or a developer item
  • choices[0].message.contentresponse.output_text
  • for tools and multimodal output, inspect response.output by item type.

Note

The _request_id attribute is available on all response objects returned by the OpenAI SDK when configured with AvalAI's base URL. This includes responses from chat completions, embeddings, images, and other endpoints.

Other SDKs

For SDKs in other languages, you typically need to access the response headers directly:

SDKMethod to Access Request ID
Python (OpenAI)response._request_id
Python (requests)response.headers.get("avalai-request-id")
JavaScript (fetch)response.headers.get("avalai-request-id")
Go (net/http)resp.Header.Get("avalai-request-id")
PHP (curl)Extract from response headers

Request Body

FieldTypeRequiredDescription
transaction_idsarrayYesList of transaction UUIDs (1-1000)

Example

bash
# First, make an API call and capture the avalai-request-id header
curl -i "https://api.avalai.ir/v1/chat/completions" \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5.4-mini",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

# Response headers will include:
# avalai-request-id: 019ac4a0-a8f4-7041-845f-3ea8f15dcf1a

# Then lookup the transaction (wait up to 30 seconds for processing)
curl -X POST "https://api.avalai.ir/user/v1/transactions/lookup" \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_ids": ["019ac4a0-a8f4-7041-845f-3ea8f15dcf1a"]
  }'
python
import requests
import time

api_key = "your-avalai-api-key"
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}

# Step 1: Make an API call and capture avalai-request-id
response = requests.post(
    "https://api.avalai.ir/v1/chat/completions",
    headers=headers,
    json={"model": "gpt-5.4-mini", "messages": [{"role": "user", "content": "Hello!"}]},
)

# Get the request ID from response headers
request_id = response.headers.get("avalai-request-id")
print(f"Request ID: {request_id}")

# Step 2: Wait for processing (up to 30 seconds)
time.sleep(5)  # Usually available much sooner

# Step 3: Lookup the transaction for precise cost
lookup_response = requests.post(
    "https://api.avalai.ir/user/v1/transactions/lookup",
    headers=headers,
    json={"transaction_ids": [request_id]},
)

transaction = lookup_response.json()
if transaction["summary"]["found"] > 0:
    tx = transaction["transactions"][0]
    print(f"Exact cost: {tx['cost']['unit']} USD")
    print(f"Exact cost: {tx['cost']['paid_irt']} IRT")
javascript
const apiKey = process.env.AVALAI_API_KEY;
const headers = {
  Authorization: `Bearer ${apiKey}`,
  "Content-Type": "application/json",
};

// Step 1: Make an API call and capture avalai-request-id
const chatResponse = await fetch("https://api.avalai.ir/v1/chat/completions", {
  method: "POST",
  headers,
  body: JSON.stringify({
    model: "gpt-5.4-mini",
    messages: [{ role: "user", content: "Hello!" }],
  }),
});

// Get the request ID from response headers
const requestId = chatResponse.headers.get("avalai-request-id");
console.log(`Request ID: ${requestId}`);

// Step 2: Wait for processing
await new Promise((resolve) => setTimeout(resolve, 5000));

// Step 3: Lookup the transaction for precise cost
const lookupResponse = await fetch(
  "https://api.avalai.ir/user/v1/transactions/lookup",
  {
    method: "POST",
    headers,
    body: JSON.stringify({ transaction_ids: [requestId] }),
  },
);

const data = await lookupResponse.json();
if (data.summary.found > 0) {
  const tx = data.transactions[0];
  console.log(`Exact cost: ${tx.cost.unit} USD`);
  console.log(`Exact cost: ${tx.cost.paid_irt} IRT`);
}
go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"os"
	"time"
)

func main() {
	apiKey := os.Getenv("AVALAI_API_KEY")

	// Step 1: Make an API call
	chatBody, _ := json.Marshal(map[string]interface{}{
		"model":    "gpt-5.4-mini",
		"messages": []map[string]string{{"role": "user", "content": "Hello!"}},
	})

	req, _ := http.NewRequest("POST", "https://api.avalai.ir/v1/chat/completions", bytes.NewBuffer(chatBody))
	req.Header.Set("Authorization", "Bearer "+apiKey)
	req.Header.Set("Content-Type", "application/json")

	resp, _ := (&http.Client{}).Do(req)
	requestID := resp.Header.Get("avalai-request-id")
	resp.Body.Close()
	fmt.Printf("Request ID: %s\n", requestID)

	// Step 2: Wait for processing
	time.Sleep(5 * time.Second)

	// Step 3: Lookup the transaction
	lookupBody, _ := json.Marshal(map[string]interface{}{
		"transaction_ids": []string{requestID},
	})

	req, _ = http.NewRequest("POST", "https://api.avalai.ir/user/v1/transactions/lookup", bytes.NewBuffer(lookupBody))
	req.Header.Set("Authorization", "Bearer "+apiKey)
	req.Header.Set("Content-Type", "application/json")

	resp, _ = (&http.Client{}).Do(req)
	defer resp.Body.Close()

	var result map[string]interface{}
	json.NewDecoder(resp.Body).Decode(&result)
	fmt.Printf("Result: %+v\n", result)
}
php
<?php
$apiKey = getenv('AVALAI_API_KEY');

// Step 1: Make an API call and capture avalai-request-id
$ch = curl_init('https://api.avalai.ir/v1/chat/completions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $apiKey,
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'model' => 'gpt-5.4-mini',
    'messages' => [['role' => 'user', 'content' => 'Hello!']]
]));

$response = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($response, 0, $headerSize);
curl_close($ch);

// Extract avalai-request-id from headers
preg_match('/avalai-request-id:\s*([^\r\n]+)/i', $headers, $matches);
$requestId = trim($matches[1] ?? '');
echo "Request ID: $requestId\n";

// Step 2: Wait for processing
sleep(5);

// Step 3: Lookup the transaction
$ch = curl_init('https://api.avalai.ir/user/v1/transactions/lookup');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $apiKey,
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'transaction_ids' => [$requestId]
]));

$lookupResponse = curl_exec($ch);
curl_close($ch);

$data = json_decode($lookupResponse, true);
if ($data['summary']['found'] > 0) {
    $tx = $data['transactions'][0];
    echo "Exact cost: " . $tx['cost']['unit'] . " USD\n";
    echo "Exact cost: " . $tx['cost']['paid_irt'] . " IRT\n";
}
?>
Responses API version

Use this version when the selected model supports /v1/responses. messages moves to input, and the final text is read from response.output_text.

python
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["AVALAI_API_KEY"],
    base_url="https://api.avalai.ir/v1",
)

response = client.responses.create(
    model="gpt-5.4-mini",
    instructions="You are a helpful assistant.",
    input="Hello!",
)

print(response.output_text)
javascript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.AVALAI_API_KEY,
  baseURL: "https://api.avalai.ir/v1",
});

const response = await client.responses.create({
  model: "gpt-5.4-mini",
  instructions: "You are a helpful assistant.",
  input: "Hello!",
});

console.log(response.output_text);
bash
curl https://api.avalai.ir/v1/responses \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AVALAI_API_KEY" \
  -d '
  {
    "model": "gpt-5.4-mini",
    "input": "Hello!",
    "instructions": "You are a helpful assistant."
  }'
  • messagesinput
  • system message → instructions or a developer item
  • choices[0].message.contentresponse.output_text
  • for tools and multimodal output, inspect response.output by item type.

Response

Example 1: Paid from UNIT balance (no credit package)

json
{
  "transactions": [
    {
      "id": "019ac4a0-a8f4-7041-845f-3ea8f15dcf1a",
      "created_at": "2025-11-27T09:24:18.129Z",
      "requested_at": "2025-11-27T09:24:14.709Z",
      "safety_identifier": null,
      "model": "gpt-5.4-mini-2026-03-17",
      "provider": "openai",
      "status_code": 200,
      "stream": false,
      "tokens": {
        "total": 17,
        "prompt": 8,
        "completion": 9,
        "reasoning": 0,
        "cached": 0,
        "prompt_details": {
          "text_tokens": 8,
          "audio_tokens": 0,
          "image_tokens": 0,
          "cached_tokens": 0,
          "audio_input_duration": 0,
          "cache_creation_tokens": 0
        },
        "completion_details": {
          "text_tokens": 9,
          "audio_tokens": 0,
          "image_tokens": 0,
          "reasoning_tokens": 0,
          "audio_output_duration": 0,
          "accepted_prediction_tokens": 0,
          "rejected_prediction_tokens": 0
        }
      },
      "ip_address": "192.168.1.1",
      "tools": {},
      "api_key_suffix": "...6I20",
      "cost": {
        "unit": "0.00000660",
        "paid_unit": "0.00000660",
        "paid_irt": "0",
        "paid_grant_irt": "0",
        "source": "credit",
        "currency": "UNIT"
      },
      "grants": [],
      "packages": []
    }
  ],
  "summary": {
    "requested": 1,
    "found": 1,
    "not_found_ids": []
  }
}

Example 2: Paid from credit package

json
{
  "transactions": [
    {
      "id": "019ac1c0-9518-7931-bf77-518cfbdd89f0",
      "created_at": "2025-11-26T20:06:22.555Z",
      "requested_at": "2025-11-26T20:00:15.228Z",
      "safety_identifier": null,
      "model": "gpt-5.4-mini",
      "provider": "openai",
      "status_code": 200,
      "stream": false,
      "tokens": {
        "total": 30,
        "prompt": 10,
        "completion": 20,
        "reasoning": 0,
        "cached": 0,
        "prompt_details": {
          "text_tokens": 10,
          "audio_tokens": 0,
          "image_tokens": 0,
          "cached_tokens": 0,
          "audio_input_duration": 0,
          "cache_creation_tokens": 0
        },
        "completion_details": {
          "text_tokens": 20,
          "audio_tokens": 0,
          "image_tokens": 0,
          "reasoning_tokens": 0,
          "audio_output_duration": 0,
          "accepted_prediction_tokens": 0,
          "rejected_prediction_tokens": 0
        }
      },
      "ip_address": "192.168.1.1",
      "tools": {},
      "api_key_suffix": "...jCqw",
      "cost": {
        "unit": "0.00001350",
        "paid_unit": "0.00001350",
        "paid_irt": "0.00",
        "paid_grant_irt": "1.55",
        "source": "credit_package",
        "currency": "UNIT"
      },
      "grants": [],
      "packages": [
        {
          "id": "1234",
          "template_id": "d-o3050s",
          "name": "مدل‌های زبانی منتخب OpenAI روزانه پایه",
          "amount_irt": "500000.00",
          "remaining_irt": "498447.15",
          "allowed_services": [
            "api"
          ],
          "scope_details": {
            "api": [
              "gpt-5-chat",
              "gpt-5.6-luna",
              "gpt-5.4-mini"
            ]
          },
          "end_date": "2025-11-27T15:05:07.404Z"
        }
      ]
    }
  ],
  "summary": {
    "requested": 1,
    "found": 1,
    "not_found_ids": []
  }
}

Response Fields

Root Object:

FieldTypeDescription
transactionsarrayArray of transaction objects
summaryobjectSummary of the lookup request

Transaction Object:

FieldTypeDescription
idstringUnique transaction identifier (UUID v7) - same as avalai-request-id header
created_atstringTransaction cost processing time (ISO 8601)
requested_atstringRequest initiation time (ISO 8601)
safety_identifierstring|nullYour internal identifier (if provided)
modelstringModel used (e.g., "gpt-5.4-mini-2026-03-17")
providerstringProvider name (e.g., "openai", "anthropic")
status_codeintHTTP response status code
streamboolWhether request used streaming
tokensobjectToken usage breakdown
ip_addressstringRequest IP address
toolsobjectTools/functions used in the request
api_key_suffixstringLast 4 characters of the API key used
costobjectCost breakdown
grantsarrayGrants used for this transaction
packagesarrayPackages used for this transaction

Tokens Object:

FieldTypeDescription
totalintTotal tokens used
promptintPrompt tokens
completionintCompletion tokens
reasoningintReasoning tokens (o1/o3 models)
cachedintCached tokens (prompt caching)
prompt_detailsobjectDetailed breakdown of prompt tokens
completion_detailsobjectDetailed breakdown of completion tokens

Prompt Details Object:

FieldTypeDescription
text_tokensintText tokens in prompt
audio_tokensintAudio tokens in prompt
image_tokensintImage tokens in prompt
cached_tokensintCached tokens in prompt
audio_input_durationintAudio input duration in seconds
cache_creation_tokensintTokens used for cache creation

Completion Details Object:

FieldTypeDescription
text_tokensintText tokens in completion
audio_tokensintAudio tokens in completion
image_tokensintImage tokens in completion
reasoning_tokensintReasoning tokens in completion
audio_output_durationintAudio output duration in seconds
accepted_prediction_tokensintAccepted prediction tokens
rejected_prediction_tokensintRejected prediction tokens

Cost Object:

FieldTypeDescription
unitstringTotal cost in USD/UNIT
paid_unitstringPaid cost in USD/UNIT
paid_irtstringPaid cost in IRT (from balance)
paid_grant_irtstringCost covered by grants/packages
sourcestringPayment source: credit, credit_package, grant, or balance
currencystringCurrency type (always "UNIT")

Summary Fields

FieldTypeDescription
requestedintNumber of IDs requested
foundintNumber of transactions found
not_found_idsarrayIDs that were not found (may still be processing)

GET /transactions/summary

Get aggregated statistics for your API usage.

URL: GET https://api.avalai.ir/user/v1/transactions/summary

Note

Time range is limited to 24 hours maximum for performance. Results are cached for 2 minutes.

Query Parameters

ParameterTypeDefaultDescription
hours_agoint24Hours to look back (1-24). Ignored if dates provided.
start_datestring-Start date (YYYY-MM-DD). Clamped to 24h max.
end_datestring-End date (YYYY-MM-DD).
safety_identifierstring-Filter by your internal identifier
api_key_idint-Filter by specific API key ID
group_bystring-Group by: day, model, safety_identifier, api_key, provider

Examples

bash
# Last 24 hours (default)
curl -X GET "https://api.avalai.ir/user/v1/transactions/summary" \
  -H "Authorization: Bearer $AVALAI_API_KEY"

# Group by model
curl -X GET "https://api.avalai.ir/user/v1/transactions/summary?group_by=model" \
  -H "Authorization: Bearer $AVALAI_API_KEY"

# Group by provider
curl -X GET "https://api.avalai.ir/user/v1/transactions/summary?group_by=provider" \
  -H "Authorization: Bearer $AVALAI_API_KEY"

# Group by API key
curl -X GET "https://api.avalai.ir/user/v1/transactions/summary?group_by=api_key" \
  -H "Authorization: Bearer $AVALAI_API_KEY"
python
import requests

api_key = "your-avalai-api-key"
headers = {"Authorization": f"Bearer {api_key}"}

# Get summary grouped by model
response = requests.get(
    "https://api.avalai.ir/user/v1/transactions/summary",
    headers=headers,
    params={"group_by": "model"},
)

summary = response.json()
print(f"Total transactions: {summary['totals']['transactions']}")
print(f"Total cost: {summary['totals']['cost']['unit']} USD")

if summary.get("by_model"):
    for model in summary["by_model"]:
        print(
            f"  {model['model']}: {model['transactions']} requests, {model['cost_unit']} USD"
        )
javascript
const apiKey = process.env.AVALAI_API_KEY;

// Get summary grouped by model
const params = new URLSearchParams({ group_by: "model" });

const response = await fetch(
  `https://api.avalai.ir/user/v1/transactions/summary?${params}`,
  {
    headers: { Authorization: `Bearer ${apiKey}` },
  },
);

const summary = await response.json();
console.log(`Total transactions: ${summary.totals.transactions}`);
console.log(`Total cost: ${summary.totals.cost.unit} USD`);

if (summary.by_model) {
  summary.by_model.forEach((model) => {
    console.log(`  ${model.model}: ${model.transactions} requests`);
  });
}
go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"os"
)

func main() {
	baseURL := "https://api.avalai.ir/user/v1/transactions/summary"
	params := url.Values{}
	params.Add("group_by", "model")

	req, _ := http.NewRequest("GET", baseURL+"?"+params.Encode(), nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AVALAI_API_KEY"))

	resp, _ := (&http.Client{}).Do(req)
	defer resp.Body.Close()

	var result map[string]interface{}
	json.NewDecoder(resp.Body).Decode(&result)

	totals := result["totals"].(map[string]interface{})
	fmt.Printf("Total transactions: %v\n", totals["transactions"])
}
php
<?php
$apiKey = getenv('AVALAI_API_KEY');

$params = http_build_query(['group_by' => 'model']);

$ch = curl_init('https://api.avalai.ir/user/v1/transactions/summary?' . $params);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $apiKey]);

$response = curl_exec($ch);
curl_close($ch);

$summary = json_decode($response, true);
echo "Total transactions: " . $summary['totals']['transactions'] . "\n";
echo "Total cost: " . $summary['totals']['cost']['unit'] . " USD\n";

if (!empty($summary['by_model'])) {
    foreach ($summary['by_model'] as $model) {
        echo "  " . $model['model'] . ": " . $model['transactions'] . " requests\n";
    }
}
?>

Response (Basic)

json
{
  "period": {
    "start": "2025-11-26T08:36:24.685Z",
    "end": "2025-11-27T08:36:24.685Z"
  },
  "totals": {
    "transactions": 1011,
    "tokens": {
      "total": 31863,
      "prompt": 11362,
      "completion": 20501,
      "reasoning": 294,
      "cached": 0
    },
    "cost": {
      "unit": "0.01466890",
      "paid_unit": "0.01466890",
      "paid_irt": "131.73",
      "paid_grant_irt": "1552.85"
    }
  },
  "breakdown": null,
  "by_model": null,
  "by_safety_identifier": null,
  "by_provider": null,
  "by_api_key": null
}

Response (with group_by=model)

json
{
  "period": {
    "start": "2025-11-26T09:09:31.342Z",
    "end": "2025-11-27T09:09:31.342Z"
  },
  "totals": {
    "transactions": 1011,
    "tokens": {
      "total": 31863,
      "prompt": 11362,
      "completion": 20501,
      "reasoning": 294,
      "cached": 0
    },
    "cost": {
      "unit": "0.01466890",
      "paid_unit": "0.01466890",
      "paid_irt": "131.73",
      "paid_grant_irt": "1552.85"
    }
  },
  "by_model": [
    {
      "model": "gpt-5.4-mini",
      "transactions": 1000,
      "tokens": 30000,
      "cost_unit": "0.01350000"
    },
    {
      "model": "gemini-2.5-flash",
      "transactions": 3,
      "tokens": 1529,
      "cost_unit": "0.00097790"
    },
    {
      "model": "deepseek-reasoner",
      "transactions": 1,
      "tokens": 114,
      "cost_unit": "0.00004720"
    }
  ]
}

Response Fields

FieldTypeDescription
period.startstringStart of the reporting period (ISO 8601)
period.endstringEnd of the reporting period (ISO 8601)
totals.transactionsintTotal number of transactions
totals.tokens.totalintTotal tokens used
totals.tokens.promptintTotal prompt tokens
totals.tokens.completionintTotal completion tokens
totals.tokens.reasoningintTotal reasoning tokens
totals.tokens.cachedintTotal cached tokens
totals.cost.unitstringTotal cost in USD/UNIT
totals.cost.paid_unitstringPaid cost in USD/UNIT
totals.cost.paid_irtstringPaid cost in IRT
totals.cost.paid_grant_irtstringCost covered by grants

Group By Fields

When using group_by, the response includes the corresponding array:

by_model:

FieldTypeDescription
modelstringModel name
transactionsintNumber of transactions
tokensintTotal tokens
cost_unitstringTotal cost in USD

by_provider:

FieldTypeDescription
providerstringProvider name
transactionsintNumber of transactions
tokensintTotal tokens

by_api_key:

FieldTypeDescription
api_key_idstringAPI key ID
api_key_suffixstringLast 4 characters of API key
transactionsintNumber of transactions
tokensintTotal tokens

by_safety_identifier:

FieldTypeDescription
safety_identifierstringYour internal identifier
transactionsintNumber of transactions
tokensintTotal tokens

GET /health

Check the health status of the User API.

URL: GET https://api.avalai.ir/user/v1/health

Request

bash
curl -X GET "https://api.avalai.ir/user/v1/health" \
  -H "Authorization: Bearer $AVALAI_API_KEY"
python
import requests

response = requests.get(
    "https://api.avalai.ir/user/v1/health",
    headers={"Authorization": f"Bearer {api_key}"},
)
print(response.json())
javascript
const response = await fetch("https://api.avalai.ir/user/v1/health", {
  headers: { Authorization: `Bearer ${process.env.AVALAI_API_KEY}` },
});
console.log(await response.json());
go
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("GET", "https://api.avalai.ir/user/v1/health", nil)
	req.Header.Set("Authorization", "Bearer "+os.Getenv("AVALAI_API_KEY"))

	resp, _ := (&http.Client{}).Do(req)
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
php
<?php
$ch = curl_init('https://api.avalai.ir/user/v1/health');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . getenv('AVALAI_API_KEY')]);

$response = curl_exec($ch);
curl_close($ch);

print_r(json_decode($response, true));
?>

Response

json
{
  "status": "healthy",
  "timestamp": "2025-11-27T09:30:00.000Z"
}

Error Handling

The User API uses standard HTTP status codes and returns JSON error responses.

Error Response Format

json
{
  "error": "error_code",
  "message": "Human-readable error description"
}

Common Errors

Status CodeError CodeDescription
400bad_requestInvalid request parameters
401unauthorizedMissing or invalid API key
403forbiddenAccount suspended or inactive
404not_foundResource not found
429rate_limit_exceededToo many requests
500internal_errorServer error