API Format

Google GenAI SDK

Installation

code
npm install @google/genai

or

code
yarn add @google/genai

Initializing the Client

code
import { GoogleGenAI } from '@google/genai';

const ai = new GoogleGenAI({
  apiKey: 'your-shopaikey-api-key',
  httpOptions: {
    baseUrl: 'https://api.shopaikey.com',
  },
});

Basic Content Generation

code
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Hello! Who are you?',
});

console.log(response.text);

Using System Instruction

code
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  config: {
    systemInstruction: 'You are an AI assistant specialized in programming.',
  },
  contents: 'Explain async/await in JavaScript',
});

console.log(response.text);

Streaming Response

code
const response = await ai.models.generateContentStream({
  model: 'gemini-2.5-flash',
  contents: 'Tell me a long story',
});

for await (const chunk of response) {
  if (chunk.text) {
    process.stdout.write(chunk.text);
  }
}

Multi-turn Chat

code
const chat = ai.chats.create({
  model: 'gemini-2.5-flash',
  config: {
    systemInstruction: 'You are a friendly assistant.',
  },
});

const response1 = await chat.sendMessage({ message: 'My name is Huy' });
console.log(response1.text);

const response2 = await chat.sendMessage({ message: 'Do you remember my name?' });
console.log(response2.text);

Chat Streaming

code
const chat = ai.chats.create({
  model: 'gemini-2.5-flash',
});

const response = await chat.sendMessageStream({ message: 'Write a poem' });

for await (const chunk of response) {
  if (chunk.text) {
    process.stdout.write(chunk.text);
  }
}

Vision API (Image Recognition)

From URL

code
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: [
    {
      role: 'user',
      parts: [
        { text: 'What is in this image? Please describe in detail.' },
        {
          fileData: {
            fileUri: 'https://example.com/image.png',
            mimeType: 'image/png',
          },
        },
      ],
    },
  ],
});

console.log(response.text);

From Base64

code
const fs = require('fs');

const imageBuffer = fs.readFileSync('./image.jpg');
const base64Image = imageBuffer.toString('base64');

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: [
    {
      role: 'user',
      parts: [
        { text: 'Describe this image' },
        {
          inlineData: {
            data: base64Image,
            mimeType: 'image/jpeg',
          },
        },
      ],
    },
  ],
});

console.log(response.text);

Video API (Video Understanding)

Gemini accepts video as input: the model reads it along the time axis, so it can answer questions that depend on what happens over time, not just the content of a single frame.

From URL

Sending by URL requires a Gemini 3 model (gemini-3-flash-preview, gemini-3-pro-preview). For gemini-2.5-flash, use the base64 form below.

code
const response = await ai.models.generateContent({
  model: 'gemini-3-flash-preview',
  contents: [
    {
      role: 'user',
      parts: [
        { text: 'What does this video explain? Summarize it step by step.' },
        {
          fileData: {
            fileUri: 'https://example.com/guide.mp4',
            mimeType: 'video/mp4',
          },
        },
      ],
    },
  ],
});

console.log(response.text);

From Base64

code
const fs = require('fs');

const base64Video = fs.readFileSync('./clip.mp4').toString('base64');

const response = await ai.models.generateContent({
  model: 'gemini-3-flash-preview',
  contents: [
    {
      role: 'user',
      parts: [
        { text: 'Describe what happens in the video, with timestamps.' },
        {
          inlineData: {
            data: base64Video,
            mimeType: 'video/mp4',
          },
        },
      ],
    },
  ],
});

console.log(response.text);

Token cost

Video costs 70 tokens per second, reported separately in usageMetadata.promptTokensDetails under modality: "VIDEO". An 85-second clip uses about 6,000 input tokens, so trim anything you do not need before sending.

Note for the OpenAI format

On /v1/chat/completions, video must be sent as an image_url part (a direct URL or a data:video/mp4;base64,... data URI). The video_url and input_video parts are dropped: the request still returns 200 and is still billed, but the model never sees the video and may answer as if it received nothing. For video understanding, prefer the native Gemini format above.

Audio API (Audio Understanding)

Gemini accepts audio files as input: use it to transcribe speech, summarize meetings, answer questions about what was said, or identify language and tone.

From URL

Sending by URL requires a Gemini 3 model (gemini-3-flash-preview, gemini-3-pro-preview). For gemini-2.5-flash, use the base64 form below.

code
const response = await ai.models.generateContent({
  model: 'gemini-3-flash-preview',
  contents: [
    {
      role: 'user',
      parts: [
        { text: 'Transcribe this recording.' },
        {
          fileData: {
            fileUri: 'https://example.com/meeting.mp3',
            mimeType: 'audio/mp3',
          },
        },
      ],
    },
  ],
});

console.log(response.text);

From Base64

code
const fs = require('fs');

const base64Audio = fs.readFileSync('./record.mp3').toString('base64');

const response = await ai.models.generateContent({
  model: 'gemini-3-flash-preview',
  contents: [
    {
      role: 'user',
      parts: [
        { text: 'Summarize the decisions made in this recording.' },
        {
          inlineData: {
            data: base64Audio,
            mimeType: 'audio/mp3',
          },
        },
      ],
    },
  ],
});

console.log(response.text);

Supported formats

audio/mp3, audio/mpeg, audio/wav, audio/aac, audio/ogg, audio/flac.

Choosing a compressed (mp3) or uncompressed (wav) format does not change the cost: the same content yields the same promptTokenCount.

Token cost

Audio costs 32 tokens per second, reported separately in usageMetadata.promptTokensDetails under modality: "AUDIO". A five-minute recording uses about 9,600 input tokens.

One caveat when reading promptTokensDetails: for compressed files, the audio tokens may be misattributed to modality: "TEXT". The promptTokenCount total stays correct, so rely on that total when reconciling cost.

A note on latency

gemini-3-pro-preview is the most accurate but processes audio very slowly. For ordinary transcription work, gemini-3-flash-preview is many times faster and accurate enough.

Function Calling

code
import { Type } from '@google/genai';

const getWeather = {
  name: 'get_weather',
  description: 'Get weather information for a location',
  parameters: {
    type: Type.OBJECT,
    properties: {
      location: {
        type: Type.STRING,
        description: 'City or location name',
      },
      unit: {
        type: Type.STRING,
        enum: ['celsius', 'fahrenheit'],
      },
    },
    required: ['location'],
  },
};

const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: "What's the weather like in Hanoi today?",
  config: {
    tools: [{ functionDeclarations: [getWeather] }],
  },
});

const functionCall = response.functionCalls?.[0];
if (functionCall) {
  console.log('Function:', functionCall.name);
  console.log('Args:', functionCall.args);
}

Advanced Configuration

code
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Write some Python code',
  config: {
    maxOutputTokens: 2048,
    temperature: 0.7,
    topP: 0.9,
    topK: 40,
  },
});

Error Handling

code
try {
  const response = await ai.models.generateContent({
    model: 'gemini-2.5-flash',
    contents: 'Hello',
  });
  console.log(response.text);
} catch (error) {
  console.error('Error:', error.message);
  if (error.status) {
    console.error('Status:', error.status);
  }
}

TypeScript Support

code
import { GoogleGenAI, GenerateContentResponse } from '@google/genai';

const ai = new GoogleGenAI({
  apiKey: process.env.SHOPAIKEY_API_KEY!,
  httpOptions: {
    baseUrl: 'https://api.shopaikey.com',
  },
});

async function chat(message: string): Promise<string> {
  const response: GenerateContentResponse = await ai.models.generateContent({
    model: 'gemini-2.5-flash',
    contents: message,
  });

  return response.text || '';
}

API Detail: Google Gemini (Native Format)

(generateContent / streamGenerateContent)

This API allows sending requests to Gemini models using Google's native format.

  • Method: POST
  • generateContent URL: https://api.shopaikey.com/v1beta/models/{model}:generateContent
  • streamGenerateContent URL: https://api.shopaikey.com/v1beta/models/{model}:streamGenerateContent

Request

Headers

NameValueRequiredDescription
AuthorizationBearer <Token>YesYour API authentication token.
Content-Typeapplication/jsonYesFormat of the request data.

Query Parameters

NameValueRequiredDescription
key<API Key>YesYour API key (automatically added by the SDK).

Body (application/json)

code
{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "Hello, please introduce yourself."
        }
      ]
    }
  ],
  "generationConfig": {
    "maxOutputTokens": 1024,
    "temperature": 1.0
  }
}

Key parameters:

  • contents (array): List of conversation content.
    • role: user or model.
    • parts: Array of content parts (text, inlineData, fileData).
  • generationConfig (object): Content generation configuration.
    • maxOutputTokens: Maximum token count.
    • temperature: Randomness (0 - 2).
    • topP, topK: Sampling parameters.
  • systemInstruction (object): System prompt.
  • tools (array): List of tools for function calling.

API Call Example (cURL)

code
curl -X POST 'https://api.shopaikey.com/v1beta/models/gemini-2.5-flash:generateContent?key=YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "Hello, please introduce yourself."
        }
      ]
    }
  ],
  "generationConfig": {
    "maxOutputTokens": 1024
  }
}'

Streaming (cURL)

code
curl -X POST 'https://api.shopaikey.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?key=YOUR_API_KEY&alt=sse' \
-H 'Content-Type: application/json' \
-d '{
  "contents": [
    {
      "role": "user",
      "parts": [
        {
          "text": "Tell me a long story."
        }
      ]
    }
  ]
}'

Response

Status: 200 OK

code
{
  "candidates": [
    {
      "content": {
        "parts": [
          {
            "text": "Hello! I'm Gemini, an AI language model developed by Google."
          }
        ],
        "role": "model"
      },
      "finishReason": "STOP"
    }
  ],
  "usageMetadata": {
    "promptTokenCount": 10,
    "candidatesTokenCount": 25,
    "totalTokenCount": 35
  }
}

Important Notes

  • Base URL: When using the SDK, set httpOptions.baseUrl to https://api.shopaikey.com
  • API Key: Use the API key from ShopAIKey; no Google Cloud API key needed
  • Models: Supports all available Gemini models (gemini-2.5-flash, gemini-2.5-pro, gemini-2.0-flash, etc.)
  • Compatibility: Fully compatible with the official Google GenAI SDK

Supported Endpoints

List Models

  • Method: GET
  • URL: https://api.shopaikey.com/v1beta/models
code
const models = await ai.models.list();
for await (const model of models) {
  console.log(model.name);
}

Generate Content

  • Method: POST
  • URL: https://api.shopaikey.com/v1beta/models/{model}:generateContent

Stream Generate Content

  • Method: POST
  • URL: https://api.shopaikey.com/v1beta/models/{model}:streamGenerateContent
code
const stream = await ai.models.generateContentStream({
  model: 'gemini-2.5-flash',
  contents: 'Tell me a long story',
});

for await (const chunk of stream) {
  process.stdout.write(chunk.text);
}

Embeddings

  • Method: POST
  • URL: https://api.shopaikey.com/v1/engines/{model}/embeddings
ParameterTypeDescription
modelstringRequired. Embedding model ID
inputstring/arrayRequired. Text to embed
encoding_formatstringFormat (float/base64)
dimensionsintegerOutput vector dimensions

Image Generation

Use responseModalities in generationConfig:

code
const response = await ai.models.generateContent({
  model: 'gemini-2.0-flash-exp',
  contents: 'Draw a cat in pixel art style',
  config: {
    responseModalities: ['TEXT', 'IMAGE'],
    imageConfig: {
      aspectRatio: '16:9',
      imageSize: '1024x1024',
    },
  },
});

Audio Generation (TTS)

Use responseModalities: ['AUDIO'] in generationConfig:

code
const response = await ai.models.generateContent({
  model: 'gemini-2.5-flash',
  contents: 'Read this passage in a natural voice.',
  config: {
    responseModalities: ['AUDIO'],
    speechConfig: {
      voiceConfig: {
        prebuiltVoiceConfig: {
          voiceName: 'Kore',
        },
      },
    },
  },
});

In this section · API Format