Intégrer l'API
La clé API ne doit jamais être appelée depuis le navigateur. Créez une route proxy serveur qui appelle l'API à votre place.
Principe du proxy
Navigateur
fetch('/api/chat')
Votre serveur
src/pages/api/chat
Zorka IA API
x-api-key: ****
La clé API reste côté serveur dans une variable d'environnement — le navigateur ne la voit jamais.
Variables d'environnement
Dans votre fichier .env :
CHATBOT_API_URL=https://api-chat.pierre-mouilleseaux-lhuillier.fr
CHATBOT_API_KEY=votre_clé_api Route API serveur
Fichier src/pages/api/chat — choisissez votre langage :
src/pages/api/chat.ts
import type { APIRoute } from "astro";
export const POST: APIRoute = async ({ request }) => {
try {
const { messages, sessionId } = await request.json();
if (!messages || !Array.isArray(messages)) {
return new Response(JSON.stringify({ error: "invalid_payload" }), {
status: 400, headers: { "Content-Type": "application/json" },
});
}
const res = await fetch(`${import.meta.env.CHATBOT_API_URL}/chat`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": import.meta.env.CHATBOT_API_KEY,
},
body: JSON.stringify({ messages, sessionId }),
});
const data = await res.json();
return new Response(JSON.stringify({ reply: data.reply }), {
status: 200, headers: { "Content-Type": "application/json" },
});
} catch {
return new Response(JSON.stringify({ error: "server_error" }), {
status: 500, headers: { "Content-Type": "application/json" },
});
}
}; src/pages/api/chat.js
export async function POST({ request }) {
try {
const { messages, sessionId } = await request.json();
if (!messages || !Array.isArray(messages)) {
return new Response(JSON.stringify({ error: "invalid_payload" }), {
status: 400, headers: { "Content-Type": "application/json" },
});
}
const res = await fetch(`${import.meta.env.CHATBOT_API_URL}/chat`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": import.meta.env.CHATBOT_API_KEY,
},
body: JSON.stringify({ messages, sessionId }),
});
const data = await res.json();
return new Response(JSON.stringify({ reply: data.reply }), {
status: 200, headers: { "Content-Type": "application/json" },
});
} catch {
return new Response(JSON.stringify({ error: "server_error" }), {
status: 500, headers: { "Content-Type": "application/json" },
});
}
} Appel depuis le navigateur
Le client appelle votre route /api/chat, jamais l'API directement.
const sessionId = crypto.randomUUID();
async function sendMessage(userMessage) {
const res = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
messages: [{ role: 'user', content: userMessage }],
sessionId,
}),
});
const { reply } = await res.json();
return reply;
}
Conservez le même sessionId tout au long d'une conversation pour maintenir le contexte.
Format de l'API
Requête
{
"messages": [
{ "role": "user", "content": "…" }
],
"sessionId": "uuid"
} Réponse
{
"reply": "Réponse de l'assistant"
}
Le header x-api-key est ajouté par votre route serveur — jamais côté navigateur.