Skip to content

Instantly share code, notes, and snippets.

@ZTRdiamond
Created June 20, 2025 11:26
Show Gist options
  • Select an option

  • Save ZTRdiamond/17cbaa83f3c6c8770aca88002487d4e2 to your computer and use it in GitHub Desktop.

Select an option

Save ZTRdiamond/17cbaa83f3c6c8770aca88002487d4e2 to your computer and use it in GitHub Desktop.
Exomlapi backend sniffed, yep it is a scraper!
import axios from "axios";
const api = axios.create({
baseURL: "https://exomlapi.com/api",
timeout: 120_000,
headers: {
'Authority': 'exomlapi.com',
'Accept': '*/*',
'Content-Type': 'application/json,*/*',
'Origin': 'https://exomlapi.com',
'Referer': 'https://exomlapi.com/',
'User-Agent': 'Zanixon/1.0.0'
}
});
// completions
async function generateAntibot() {
const res = await api.post('/genid');
const data = res.data;
if (!data?.antiBotId) throw 'failed fetch antibot id!';
return data;
}
function parseRawtext(input) {
const matches = [...input.matchAll(/\d+:"(.*?)"/g)];
return matches.map(m => m[1]).join("");
}
async function completions(payload = {}) {
try {
return await new Promise(async (resolve, reject) => {
const models = [
"llama",
"gemma",
"qwen-3-235b",
"gpt-4.1",
"gpt-4o",
"gpt-4o-mini",
"llama-4-scout",
"llama-4-maverick",
"deepseek-r1",
"qwq-32b"
];
if (!payload?.model) return reject('missing model, please input the model first!');
if (!models.includes(payload?.model)) return reject('invalid model, please input the model correctly!', models);
if (!payload?.messages) return reject('missing messages input!');
if (!Array.isArray(payload.messages)) return reject('invalid array messages, please input the payload correctly!');
const id = Math.floor(Math.random() * 9999999999) + 1;
const chatId = `chat-${Date.now()}-${Math.floor(Math.random() * 999999) + 1}`;
const userId = `local-user-${Date.now()}-${Math.floor(Math.random() * 9999999) + 1}`;
const antiBotId = (await generateAntibot().catch(reject))?.antiBotId;
api.post('/chat', {
id,
chatId,
userId,
antiBotId,
messages: payload.messages,
model: payload.model,
systemPrompt: payload?.systemPrompt || '',
isAuthenticated: true
}).then(res => {
const answer = parseRawtext(res.data);
if (!answer) return reject('failed get response.');
return resolve({ success: true, answer });
}).catch(reject);
});
} catch (e) {
return {
success: false,
errors: e
};
}
}
async function llmSearch(query, count = 10) {
try {
return await new Promise(async(resolve, reject) => {
if(!query) return reject('missing query input!');
if(!count) return reject('missing count input!');
if(!Number.isInteger(count)) return reject('invalid number inpur at count param!');
axios.post('https://search.exomlapi.com/api/ml_search', {
query,
count
}, {
headers: {
'Accept': '*/*',
'Content-Type': 'application/json',
'Origin': 'https://exomlapi.com',
'Referer': 'https://exomlapi.com/',
'User-Agent': 'Zanixon/1.0.0'
}
}).then(res => {
const data = res.data;
if(!data?.llm_response) return reject('failed generate response!');
return resolve({
success: true,
result: {
answer: data?.llm_response,
searchResult: data?.results.map(d => ({
url: d.url,
title: d.title,
description: d.text
}))
}
})
})
})
} catch (e) {
return {
success: false,
errors: e
}
}
}
// image generation
async function enhancePrompt(prompt) {
try {
return await new Promise(async(resolve, reject) => {
if(!prompt) return reject('missing prompt input!');
api.post('/prompts/enhance', {
prompt
}).then(res => {
const data = res.data;
if(!data?.enhancedPrompt) return reject('failed generate response!');
return resolve({
success: true,
prompt: data?.enhancedPrompt
})
})
})
} catch (e) {
return {
success: false,
errors: e
}
}
}
async function generateImage(prompt, model = "exo-image") {
try {
return await new Promise(async(resolve, reject) => {
const models = [
"exo-image",
"flux.1-schnell",
"flux.1-pro",
"flux.1-dev"
]
if(!prompt) return reject('missing prompt input!');
if(!models.includes(model)) return reject('invalid model input!', models)
api.post('/images/generate', {
prompt,
model,
size: '1024x1024'
}).then(res => {
const data = res.data;
if(data?.data.length < 1) return reject('failed generate response!');
return resolve({
success: true,
result: data?.data.map(d => ({
url: d.url,
prompt: d.revised_prompt
}))
})
})
})
} catch (e) {
return {
success: false,
errors: e
}
}
}
@ZTRdiamond
Copy link
Author

πŸ•·οΈ ExoML API Scraper

Unofficial wrapper/scraper untuk layanan ExoML API, yang menyediakan antarmuka untuk:

  • Chat completions (berbagai model)
  • Prompt enhancer untuk image gen
  • Image generation
  • LLM-powered web search

⚠️ Unofficial client – gunakan dengan bijak. Endpoint bisa berubah sewaktu-waktu.


πŸ“¦ Instalasi

npm install axios

πŸ“ Struktur Modul

β”œβ”€β”€ api               # Axios instance dengan config khusus ExoML
β”œβ”€β”€ generateAntibot   # Mengambil antiBotId (wajib sebelum request chat)
β”œβ”€β”€ completions       # LLM chat completions
β”œβ”€β”€ parseRawtext      # Utility parser hasil raw response ExoML
β”œβ”€β”€ llmSearch         # Search + LLM summarizer
β”œβ”€β”€ enhancePrompt     # Prompt enhancer untuk image generation
β”œβ”€β”€ generateImage     # Image generator berbasis prompt

πŸ“˜ API Docs

πŸ” generateAntibot()

Ambil antiBotId yang diperlukan sebelum mengirim permintaan ke endpoint chat.

const id = await generateAntibot();
console.log(id.antiBotId); // string

🧠 completions(payload)

Mengirim permintaan completion berbasis chat. Butuh array messages dan model.

await completions({
  model: "gpt-4o",
  messages: [
    { role: "user", content: "Apa itu ExoML?" }
  ],
  systemPrompt: "Kamu adalah AI asisten."
});

βœ… Payload

Key Tipe Wajib Deskripsi
model string βœ… Salah satu dari daftar model
messages array βœ… Array pesan (role: user/system)
systemPrompt string ❌ Prompt sistem opsional

πŸ§ͺ Model yang didukung:

  • "llama"
  • "gemma"
  • "qwen-3-235b"
  • "gpt-4.1"
  • "gpt-4o"
  • "gpt-4o-mini"
  • "llama-4-scout"
  • "llama-4-maverick"
  • "deepseek-r1"
  • "qwq-32b"

πŸ” llmSearch(query, count = 10)

Search berbasis query + LLM summarization dari hasil web.

await llmSearch("cara kerja AI");

βœ… Hasil:

{
  success: true,
  result: {
    answer: "Penjelasan singkat...",
    searchResult: [
      {
        url: "https://example.com",
        title: "Artikel AI",
        description: "Isi ringkasan dari halaman..."
      }
    ]
  }
}

πŸͺ„ enhancePrompt(prompt)

Meningkatkan prompt sebelum digunakan untuk image generation.

await enhancePrompt("a castle in the sky");

πŸ–ΌοΈ generateImage(prompt, model)

Generate gambar dari prompt. Default model: "exo-image"

await generateImage("A cyberpunk cityscape at night", "flux.1-pro");

🎨 Model yang tersedia:

  • "exo-image"
  • "flux.1-schnell"
  • "flux.1-pro"
  • "flux.1-dev"

πŸ› οΈ Utils

πŸ”§ parseRawtext(input)

Utility internal untuk parsing raw response dari chat completion.

const text = parseRawtext(`1:"Hello world!" 2:"Another part"`);
console.log(text); // "Hello world!Another part"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment