مرجع API — نمای کلی

اسکیمای درخواست و پاسخ آشا بسیار شبیه به OpenAI Chat API است، با چند تفاوت کوچک. به بیان ساده، آشا اسکیما را در بین مدل‌ها و ارائه‌دهنده‌ها عادی‌سازی می‌کند ؛ پس فقط باید یک API را یاد بگیرید.

درخواست‌ها

قالب درخواست Completion

در اینجا اسکیمای درخواست به‌صورت یک تایپ TypeScript آمده است. این فیلدها بدنهٔ درخواست POST شما به endpointِ /v1/chat/completions هستند (نمونه را در شروع سریع ببینید). برای فهرست کامل پارامترها، بخش Parameters را ببینید.

TypeScript Request Schema
// Definitions of subtypes are below
type Request = {
  // Either "messages" or "prompt" is required
  messages?: Message[];
  prompt?: string;

  // If "model" is unspecified, uses the user's default
  model?: string; // See "Supported Models" section

  // Allows to force the model to produce specific output format.
  // See "Structured Outputs" section below and models page for which models support it.
  response_format?: ResponseFormat;

  stop?: string | string[];
  stream?: boolean; // Enable streaming

  // Plugins to extend model capabilities (PDF parsing, response healing)
  // See "Plugins" section
  plugins?: Plugin[];

  // See LLM Parameters (docs-api-ref-parameters)
  max_tokens?: number; // Range: [1, context_length)
  temperature?: number; // Range: [0, 2]

  // Tool calling
  // Will be passed down as-is for providers implementing OpenAI's interface.
  // For providers with custom interfaces, we transform and map the properties.
  // Otherwise, we transform the tools into a YAML template. The model responds with an assistant message.
  // See models supporting tool calling: docs-models.html
  tools?: Tool[];
  tool_choice?: ToolChoice;

  // Advanced optional parameters
  seed?: number; // Integer only
  top_p?: number; // Range: (0, 1]
  top_k?: number; // Range: [1, Infinity) Not available for OpenAI models
  frequency_penalty?: number; // Range: [-2, 2]
  presence_penalty?: number; // Range: [-2, 2]
  repetition_penalty?: number; // Range: (0, 2]
  logit_bias?: { [key: number]: number };
  top_logprobs: number; // Integer only
  min_p?: number; // Range: [0, 1]
  top_a?: number; // Range: [0, 1]

  // Reduce latency by providing the model with a predicted output
  prediction?: { type: 'content'; content: string };

  // Asha-only parameters
  // See "Model Routing" section
  models?: string[];
  route?: 'fallback';
  // See "Provider Routing" section
  provider?: ProviderPreferences;
  user?: string; // A stable identifier for your end-users. Used to help detect and prevent abuse.

  // Debug options (streaming only)
  debug?: {
    echo_upstream_body?: boolean; // If true, returns the transformed request body sent to the provider
  };
};

// Subtypes:

type TextContent = {
  type: 'text';
  text: string;
};

type ImageContentPart = {
  type: 'image_url';
  image_url: {
    url: string; // URL or base64 encoded image data
    detail?: string; // Optional, defaults to "auto"
  };
};

type ContentPart = TextContent | ImageContentPart;

type Message =
  | {
      role: 'user' | 'assistant' | 'system';
      // ContentParts are only for the "user" role:
      content: string | ContentPart[];
      // If "name" is included, it will be prepended like this
      // for non-OpenAI models: `{name}: {content}`
      name?: string;
    }
  | {
      role: 'tool';
      content: string;
      tool_call_id: string;
      name?: string;
    };

type FunctionDescription = {
  description?: string;
  name: string;
  parameters: object; // JSON Schema object
};

type Tool = {
  type: 'function';
  function: FunctionDescription;
};

type ToolChoice =
  | 'none'
  | 'auto'
  | {
      type: 'function';
      function: {
        name: string;
      };
    };

// Response format for structured outputs
type ResponseFormat =
  | { type: 'json_object' }
  | {
      type: 'json_schema';
      json_schema: {
        name: string;
        strict?: boolean;
        schema: object; // JSON Schema object
      };
    };

// Plugin configuration
type Plugin = {
  id: string; // 'web', 'file-parser', 'response-healing', 'context-compression'
  enabled?: boolean;
  // Additional plugin-specific options
  [key: string]: unknown;
};

خروجی‌های ساختاریافته

پارامتر response_format به شما اجازه می‌دهد پاسخ‌های ساختاریافتهٔ JSON را از مدل بگیرید. آشا از دو حالت پشتیبانی می‌کند:

  • { type: 'json_object' }: حالت JSON پایه — مدل JSON معتبر برمی‌گرداند.
  • { type: 'json_schema', json_schema: { ... } }: حالت اسکیمای سختگیرانه — مدل JSONِ منطبق بر اسکیمای دقیق شما برمی‌گرداند.

برای مثال‌های مفصل، مستندات Structured Outputs را ببینید. برای یافتن مدل‌هایی که خروجی ساختاریافته را پشتیبانی می‌کنند، بخش «Structured Outputs» در صفحهٔ مدل‌ها را بررسی کنید.

پلاگین‌ها

پلاگین‌های آشا قابلیت‌های مدل را با ویژگی‌هایی مثل جست‌وجوی وب، پردازش PDF، «پاسخ‌درمانی» (response healing) و فشرده‌سازی بافت گسترش می‌دهند. با افزودن یک آرایهٔ plugins به درخواست، پلاگین را فعال کنید:

JSON request body
{
  "plugins": [
    { "id": "web" },
    { "id": "response-healing" }
  ]
}

پلاگین‌های موجود شامل web (جست‌وجوی وب زنده)، file-parser (پردازش PDF)، response-healing (تعمیر خودکار JSON) و context-compression (فشرده‌سازی prompt به روش middle-out) هستند. برای گزینه‌های پیکربندی دقیق، مستندات Plugins را ببینید.

نکته: اگر پارامتر model حذف شود، از مدل پیش‌فرض کاربر استفاده می‌شود. در غیر این صورت حتماً یک مقدار برای model از بین مدل‌های پشتیبانی‌شده انتخاب کنید و prefix سازمان را نیز شامل شود. آشا کم‌هزینه‌ترین و بهترین GPUهای موجود را برای سرویس‌دهی درخواست انتخاب می‌کند و اگر کد پاسخ 5xx بگیرد یا rate-limit شوید، به ارائه‌دهنده یا GPU دیگری fallback می‌کند.
نکته: رویدادهای ارسال‌شده توسط سرور (SSE) هم پشتیبانی می‌شوند تا برای همهٔ مدل‌ها استریمینگ فعال شود. کافی است در بدنهٔ درخواست stream: true بفرستید. جریان SSE گهگاه یک payload از نوع «comment» دارد که باید نادیده گرفته شود (در زیر ذکر شده).
نکته: اگر مدل انتخاب‌شده از پارامتری (مثل logit_bias در مدل‌های غیر-OpenAI یا top_k برای OpenAI) پشتیبانی نکند، آن پارامتر نادیده گرفته می‌شود. بقیه پارامترها به API مدل اصلی منتقل می‌شوند.

پیش‌پر کردن پاسخ دستیار

آشا از اینکه مدل یک پاسخ ناقص را کامل کند پشتیبانی می‌کند. این کار برای هدایت مدل به سمت یک سبک پاسخ می‌تواند مفید باشد. برای این کار، کافی است یک پیام با role: "assistant" در انتهای آرایهٔ messages قرار دهید.

TypeScript fetch
fetch('https://app.asha-ai.ir/v1/chat/completions', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer <ASHA_API_KEY>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: '~openai/gpt-latest',
    messages: [
      { role: 'user', content: 'What is the meaning of life?' },
      { role: 'assistant', content: "I'm not sure, but my best guess is" },
    ],
  }),
});

پاسخ‌ها

قالب پاسخ Completion

آشا اسکیما را در بین مدل‌ها و ارائه‌دهنده‌ها عادی‌سازی می‌کند تا با OpenAI Chat API سازگار باشد.

یعنی choices همیشه یک آرایه است، حتی اگر مدل فقط یک completion برگرداند. هر choice اگر استریم درخواست شده باشد یک خاصیت delta و در غیر این صورت یک خاصیت message دارد. این کار استفاده از کد یکسان برای همهٔ مدل‌ها را آسان‌تر می‌کند. اسکیمای پاسخ به‌صورت تایپ TypeScript در زیر آمده است:

TypeScript Response schema
// Definitions of subtypes are below
type Response = {
  id: string;
  // Depending on whether you set "stream" to "true" and
  // whether you passed in "messages" or a "prompt", you
  // will get a different output shape
  choices: (NonStreamingChoice | StreamingChoice | NonChatChoice)[];
  created: number; // Unix timestamp
  model: string;
  object: 'chat.completion' | 'chat.completion.chunk';

  system_fingerprint?: string; // Only present if the provider supports it

  // Usage data is always returned for non-streaming.
  // When streaming, usage is returned exactly once in the final chunk
  // before the [DONE] message, with an empty choices array.
  usage?: ResponseUsage;
};
TypeScript ResponseUsage
// Asha always returns detailed usage information.
// Token counts are calculated using the model's native tokenizer.

type ResponseUsage = {
  /** Including images, input audio, and tools if any */
  prompt_tokens: number;
  /** The tokens generated */
  completion_tokens: number;
  /** Sum of the above two fields */
  total_tokens: number;

  /** Breakdown of prompt tokens (optional) */
  prompt_tokens_details?: {
    cached_tokens: number;        // Tokens cached by the endpoint
    cache_write_tokens?: number;  // Tokens written to cache (models with explicit caching)
    audio_tokens?: number;        // Tokens used for input audio
    video_tokens?: number;        // Tokens used for input video
  };

  /** Breakdown of completion tokens (optional) */
  completion_tokens_details?: {
    reasoning_tokens?: number;    // Tokens generated for reasoning
    audio_tokens?: number;        // Tokens generated for audio output
    image_tokens?: number;        // Tokens generated for image output
  };

  /** Cost in credits (optional) */
  cost?: number;
  /** Whether request used Bring Your Own Key */
  is_byok?: boolean;
  /** Detailed cost breakdown (optional) */
  cost_details?: {
    upstream_inference_cost?: number;
    upstream_inference_prompt_cost: number;
    upstream_inference_completions_cost: number;
  };

  /** Server-side tool usage (optional) */
  server_tool_use?: {
    web_search_requests?: number;
  };
};
TypeScript Subtypes
type NonChatChoice = {
  finish_reason: string | null;
  text: string;
  error?: ErrorResponse;
};

type NonStreamingChoice = {
  finish_reason: string | null;
  native_finish_reason: string | null;
  message: {
    content: string | null;
    role: string;
    tool_calls?: ToolCall[];
  };
  error?: ErrorResponse;
};

type StreamingChoice = {
  finish_reason: string | null;
  native_finish_reason: string | null;
  delta: {
    content: string | null;
    role?: string;
    tool_calls?: ToolCall[];
  };
  error?: ErrorResponse;
};

type ErrorResponse = {
  code: number; // See "Error Handling" section
  message: string;
  metadata?: Record<string, unknown>; // Contains additional error information such as provider details, the raw error message, etc.
};

type ToolCall = {
  id: string;
  type: 'function';
  function: FunctionCall;
};

در اینجا یک مثال آمده است:

JSON Example
{
  "id": "gen-xxxxxxxxxxxxxx",
  "choices": [
    {
      "finish_reason": "stop", // Normalized finish_reason
      "native_finish_reason": "stop", // The raw finish_reason from the provider
      "message": {
        // will be "delta" if streaming
        "role": "assistant",
        "content": "Hello there!"
      }
    }
  ],
  "usage": {
    "prompt_tokens": 10,
    "completion_tokens": 4,
    "total_tokens": 14,
    "prompt_tokens_details": {
      "cached_tokens": 0
    },
    "completion_tokens_details": {
      "reasoning_tokens": 0
    },
    "cost": 0.00014
  },
  "model": "~openai/gpt-latest" // Could also be "~anthropic/claude-sonnet-4", etc, depending on the "model" that ends up being used
}

دلیل پایان

آشا finish_reason هر مدل را به یکی از مقادیر زیر عادی‌سازی می‌کند: tool_calls، stop، length، content_filter، error.

بعضی مدل‌ها و ارائه‌دهنده‌ها ممکن است دلیل پایان اضافی داشته باشند. رشتهٔ خام دلخواهِ finish_reason که توسط مدل برگردانده می‌شود، از طریق خاصیت native_finish_reason در دسترس است.

پرس‌وجوی هزینه و آمار

تعداد token های برگشتی در پاسخ API با استفاده از tokenizer بومی مدل محاسبه می‌شود. مصرف اعتبار و قیمت‌گذاری مدل بر اساس همین تعداد token بومی است.

تعداد token ها در فیلد usage بدنهٔ پاسخ هم برای completion های غیر استریمی در دسترس است.