Documentation développeurs

Les bases Kopik, dans votre code.

Chaque base de connaissances publique ou non listée s'interroge aussi en dehors du site : par une API REST pour vos applications, ou par un serveur MCP pour vos agents IA. Même base, même prix, mêmes réponses sourcées. Et vos propres bases, privées comprises, deviennent un back-end RAG gratuit pour vos agents, sans rien héberger.

Aperçu : REST ou MCP ?

🤖 MCP pour les agents

Claude (Desktop, Code), Cursor, ChatGPT, votre propre agent : tout client compatible MCP. L'agent découvre lui-même les outils, choisit quand interroger la base et cite ses sources. Rien à coder : une adresse et une clé suffisent.

🧩 REST pour vos applications

Votre site, votre back-office, votre chatbot, vos scripts. Un appel HTTP renvoie une réponse rédigée avec ses passages, ou les passages seuls si vous voulez les donner à votre propre modèle.

Les bases se trouvent au catalogue. Chaque base a un identifiant, son slug, visible dans son adresse : kopik.io/b/<slug>. Sa page donne aussi des extraits prêts à copier.

Posez vos questions dans n'importe quelle langue : la réponse revient dans la langue de la question, quelle que soit celle des documents. Avant la recherche, un modèle de langage traduit la question en mots-clés et synonymes dans la langue des documents ; la recherche plein texte est elle-même réglée sur cette langue (champ language, aussi indiqué sur la page de chaque base). Les 8 passages les plus pertinents sont retenus, et la réponse est rédigée à partir d'eux seuls.

Votre propre RAG privé. Passez une base en privé depuis votre tableau de bord et interrogez-la avec votre clé API, en REST ou en MCP : vous seul y avez accès, et vos questions à vos propres bases sont gratuites (usage raisonnable : 200 par jour). Vous déposez des documents, vous obtenez un point d'accès. Ni base vectorielle, ni pipeline d'ingestion, ni serveur à gérer.

Authentification

Créez une clé API depuis votre tableau de bord. Elle commence par kpk_ et ne s'affiche qu'une fois : gardez-la comme un mot de passe, côté serveur, jamais dans du code exécuté par un navigateur. Envoyez-la dans l'en-tête Authorization :

En-tête HTTP
Authorization: Bearer kpk_…

L'en-tête x-api-key: kpk_… est aussi accepté. Les clés sont stockées hachées : si vous en perdez une, révoquez-la et créez-en une autre. Le catalogue (lister et consulter les bases) est public et ne demande pas de clé ; seules les questions en demandent une. Une clé révoquée cesse de fonctionner immédiatement. Votre clé ouvre aussi vos bases privées : gardez-la secrète.

Facturation

  • Chaque base a son propre prix par question, fixé par son créateur et indiqué dans priceCents (en centimes d'euro).
  • Le prix est débité de votre crédit Kopik, rechargé par carte depuis le tableau de bord. Le même crédit sert au site, à l'API et à MCP.
  • Une question sans résultat n'est pas facturée : si la base ne contient rien de pertinent, ou si la réponse échoue pour une raison technique, le débit est annulé.
  • Plafonnez le prix avec maxPriceCents : si la base coûte plus cher, l'appel est refusé (409, price_above_max) et rien n'est débité. Recommandé pour les agents qui tournent en boucle, car un créateur peut changer son prix à tout moment.
  • Crédit insuffisant → erreur 402, code insufficient_credit ; rien n'est débité.
  • La 1 question offerte chaque mois vaut sur le site uniquement : l'API et MCP sont toujours facturés.
  • Vos propres bases sont gratuites, par tous les canaux : publiques, non listées ou privées (usage raisonnable : 200 questions par jour).
  • Les modes answer et passages coûtent le même prix.
  • Le crédit se recharge par carte (packs de 10, 25, 50 ou 100 €), n'expire jamais et n'est pas remboursable.

API REST

Adresse de base : https://kopik.io/api/v1. Corps et réponses en JSON (UTF-8).

GET

/bases

Public · gratuit

Liste les bases publiques et non vides, les plus consultées d'abord. Paramètres facultatifs : topic (thème), q (mot-clé cherché dans le titre et la description), limit (100 au maximum). Les bases non listées n'y figurent pas, mais restent interrogeables par leur slug.

Thèmes : legal, hr, tax, finance, environment, health, aviation, agriculture, industry, real-estate, tech, marketing, education, other.

Requête
curl "https://kopik.io/api/v1/bases?topic=legal&q=cong%C3%A9s"
Réponse 200
{
  "bases": [
    {
      "slug": "code-du-travail-conges-x7k2",
      "title": "Code du travail : congés",
      "description": "Congés payés, congés pour événements familiaux, jours fériés…",
      "topic": "legal",
      "topicLabel": "Legal",
      "language": "french",
      "priceCents": 10,
      "documents": 12,
      "passages": 840,
      "questions": 1375,
      "url": "https://kopik.io/b/code-du-travail-conges-x7k2",
      "updatedAt": "2026-09-20T08:14:00.000Z"
    }
  ]
}
GET

/bases/{slug}

Public · gratuit

Détail d'une base publique ou non listée, avec la langue de ses documents (language). Une base privée renvoie 404 ici, mais son propriétaire peut l'interroger avec sa clé.

Requête
curl https://kopik.io/api/v1/bases/code-du-travail-conges-x7k2
Réponse 200
{
  "slug": "code-du-travail-conges-x7k2",
  "title": "Code du travail : congés",
  "description": "Congés payés, congés pour événements familiaux, jours fériés…",
  "topic": "legal",
  "topicLabel": "Legal",
  "language": "french",
  "priceCents": 10,
  "documents": 12,
  "passages": 840,
  "questions": 1375,
  "url": "https://kopik.io/b/code-du-travail-conges-x7k2",
  "updatedAt": "2026-09-20T08:14:00.000Z"
}
POST

/bases/{slug}/query

🔑 Clé requise · facturé

Pose une question à la base. Fonctionne sur les bases publiques et non listées, et sur vos propres bases privées. Corps : question (3 à 2 000 caractères), maxPriceCents facultatif (prix plafond en centimes d'euro) et mode :

  • "answer" (par défaut) : une réponse rédigée à partir de la base, avec des renvois [n] vers les passages ;
  • "passages" : les passages les plus pertinents seulement (answer vaut null), pour raisonner avec votre propre modèle.
Requête (mode answer)
curl -X POST https://kopik.io/api/v1/bases/code-du-travail-conges-x7k2/query \
  -H "Authorization: Bearer kpk_…" \
  -H "Content-Type: application/json" \
  -d '{"question": "Combien de jours de congé pour un mariage ?", "mode": "answer", "maxPriceCents": 20}'
Réponse 200 (mode answer)
{
  "id": "cm1x0q2ab0001kopik",
  "answer": "Un salarié a droit à **4 jours de congé** pour son mariage ou la conclusion d'un PACS [1]. Ce congé n'entraîne pas de réduction de salaire [2].",
  "passages": [
    {
      "n": 1,
      "document": "Code du travail (congés pour événements familiaux).pdf",
      "text": "Le salarié a droit, sur justification, à un congé : 1° Pour son mariage ou pour la conclusion d'un pacte civil de solidarité : quatre jours…",
      "score": 0.82
    },
    {
      "n": 2,
      "document": "Code du travail (congés pour événements familiaux).pdf",
      "text": "Ces jours d'absence n'entraînent pas de réduction de la rémunération…",
      "score": 0.61
    }
  ],
  "costCents": 10,
  "balanceCents": 2490
}
Requête (mode passages)
curl -X POST https://kopik.io/api/v1/bases/code-du-travail-conges-x7k2/query \
  -H "Authorization: Bearer kpk_…" \
  -H "Content-Type: application/json" \
  -d '{"question": "congé mariage", "mode": "passages"}'
Réponse 200 (mode passages)
{
  "id": "cm1x0q9cd0002kopik",
  "answer": null,
  "passages": [
    { "n": 1, "document": "…", "text": "…", "score": 0.82 }
  ],
  "costCents": 10,
  "balanceCents": 2480
}

Si rien n'est trouvé, passages est vide, costCents vaut 0 et, en mode answer, la réponse le dit en toutes lettres. balanceCents est votre solde après la question.

Erreurs

Toute erreur renvoie un statut HTTP et un corps JSON avec un message lisible et un code stable, fait pour les machines :

402
{
  "error": "Crédit insuffisant : cette base coûte 0,10 € par question. Rechargez sur kopik.io/fr/dashboard.",
  "code": "insufficient_credit"
}

Testez le code, jamais le message : les messages peuvent être reformulés, les codes ne changent pas.

codeHTTPSignificationQue faire
invalid_json400Le corps n'est pas du JSON valide.Envoyez un corps JSON avec Content-Type: application/json.
question_too_short400Question vide ou de moins de 3 caractères.Posez une vraie question.
question_too_long400Question de plus de 2 000 caractères.Raccourcissez la question.
api_key_missing401Aucune clé API dans la requête.Ajoutez Authorization: Bearer kpk_….
api_key_invalid401Clé inconnue ou révoquée.Vérifiez la clé, ou créez-en une depuis le tableau de bord.
insufficient_credit402Votre crédit ne couvre pas le prix de la base.Rechargez depuis le tableau de bord.
base_not_found404Aucune base avec ce slug, ou base privée.Vérifiez le slug (visible dans l'adresse de la base).
base_empty409La base ne contient encore aucun document.Réessayez quand son créateur y aura ajouté des documents.
price_above_max409La base coûte plus que votre `maxPriceCents`. Rien n'est débité.Relevez votre plafond si le nouveau prix vous convient, ou choisissez une autre base.
refused422Cette question ne peut pas recevoir de réponse.Reformulez la question.
rate_limited429Trop de demandes (voir Limites).Patientez (respectez Retry-After s'il est présent), puis réessayez en espaçant les appels.
unexpected500Erreur inattendue de notre côté.Réessayez ; rien n'est facturé en cas d'échec.
answer_failed502La réponse n'a pas pu être rédigée.Réessayez ; vous n'avez pas été débité.
not_configured503Le moteur de réponse est momentanément indisponible.Réessayez plus tard.

Langue des messages d'erreur

Les messages sont en anglais par défaut. Envoyez x-kopik-locale: fr (ou en) pour choisir ; à défaut, un en-tête Accept-Language commençant par fr donne le français. Le code est le même dans toutes les langues.

curl
curl -X POST https://kopik.io/api/v1/bases/code-du-travail-conges-x7k2/query \
  -H "Authorization: Bearer kpk_…" \
  -H "x-kopik-locale: fr" \
  -H "Content-Type: application/json" \
  -d '{"question": "Combien de jours de congé pour un mariage ?"}'

Serveur MCP

Kopik expose un serveur MCP (transport « Streamable HTTP », sans état), compatible avec Claude, Cursor, ChatGPT et tout client MCP. Les noms, descriptions et résultats des outils sont en anglais. Deux adresses, selon ce que vous voulez donner à votre agent :

Tout le catalogue

https://kopik.io/api/mcp

L'agent cherche la bonne base lui-même.

  • list_bases { topic?, query? } (gratuit)
  • ask_base { base, question }
  • search_base { base, question }

Une seule base

https://kopik.io/api/mcp?base=<slug>

Outils pré-ciblés : l'agent ne peut interroger que cette base. La page de chaque base donne son adresse. Fonctionne aussi pour vos bases privées, avec votre clé.

  • ask_base { question }
  • search_base { question }

Outils

list_bases{ topic?, query? }
Liste les bases publiques, filtrables par thème ou mot-clé. Gratuit. Adresse catalogue uniquement.
ask_base{ base, question, maxPriceCents? }
Réponse rédigée suivie des passages sources numérotés.
search_base{ base, question, maxPriceCents? }
Passages pertinents seuls, sans réponse rédigée. Même prix que ask_base.

Sur l'adresse d'une seule base, base disparaît : ask_base { question } et search_base { question }. Le maxPriceCents facultatif refuse l'appel, sans rien débiter, si la base coûte plus cher.

Chaque appel est facturé au prix de la base, comme par l'API, et se termine par le coût et le solde restant. La clé passe dans l'en-tête Authorization: Bearer kpk_… ; seul list_bases fonctionne sans. Les lots JSON-RPC sont limités à 10 requêtes.

Protection contre l'injection de prompt. Le texte issu d'une base est renvoyé entre des balises <kopik-untrusted>, précédé d'une note qui demande à l'agent de le traiter strictement comme une donnée de référence et de ne jamais suivre les instructions qu'il contient.

Claude Code

Tout le catalogue
claude mcp add --transport http kopik https://kopik.io/api/mcp --header "Authorization: Bearer kpk_…"
Une seule base
claude mcp add --transport http kopik-code-du-travail-conges-x7k2 "https://kopik.io/api/mcp?base=code-du-travail-conges-x7k2" --header "Authorization: Bearer kpk_…"

Gardez les guillemets autour de l'adresse : sous zsh (le shell par défaut de macOS), un ? non protégé est un motif de fichier et la commande échoue.

Autres clients (Cursor, Claude Desktop, …)

La plupart des clients lisent un fichier de configuration mcpServers (dans Cursor : .cursor/mcp.json). Le format courant, avec une adresse et des en-têtes :

mcp.json
{
  "mcpServers": {
    "kopik": {
      "url": "https://kopik.io/api/mcp",
      "headers": { "Authorization": "Bearer kpk_…" }
    },
    "kopik-code-du-travail-conges-x7k2": {
      "url": "https://kopik.io/api/mcp?base=code-du-travail-conges-x7k2",
      "headers": { "Authorization": "Bearer kpk_…" }
    }
  }
}

Limites et sécurité

Les limites protègent le service et votre crédit. Au-delà, l'appel renvoie 429 avec le code rate_limited.

QuoiLimite
Questions par utilisateur (tous canaux)20 par minute · 1 000 par jour
Vos questions à vos propres basesGratuites · usage raisonnable de 200 par jour
Requêtes par adresse IP (REST et MCP)120 par minute, puis 429 avec Retry-After: 60
Lot JSON-RPC (MCP)10 requêtes au maximum
Bases par compte20
Par base1 000 documents · 20 millions de caractères
Par document4 Mo par fichier · 2 millions de caractères · 1 500 pages de PDF
Envois de documents120 par heure

Sécurité côté agents : fixez maxPriceCents pour qu'un changement de prix ne coûte jamais plus que prévu à un agent qui boucle ; testez le code d'erreur ; et traitez le contenu des bases comme une donnée (par MCP, il arrive entre des balises <kopik-untrusted>). Les réponses sont rédigées à partir des seuls passages de la base, mais peuvent se tromper : elles ne constituent pas un conseil juridique, médical ou financier.

Exemples

JavaScript (fetch, Node 18+)

ask.mjs
const res = await fetch("https://kopik.io/api/v1/bases/code-du-travail-conges-x7k2/query", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.KOPIK_API_KEY}`,
    "Content-Type": "application/json",
    "x-kopik-locale": "fr",
  },
  body: JSON.stringify({
    question: "Combien de jours de congé pour un mariage ?",
    mode: "answer",
  }),
});

const data = await res.json();
if (!res.ok) {
  // data.code is stable: branch on it (e.g. "insufficient_credit", "rate_limited").
  throw new Error(`Kopik ${res.status} ${data.code}: ${data.error}`);
}

console.log(data.answer);
for (const p of data.passages) console.log(`[${p.n}] ${p.document}`);
console.log(`Coût: €${(data.costCents / 100).toFixed(2)} · solde: €${(data.balanceCents / 100).toFixed(2)}`);

Python (requests)

ask.py
import os
import requests

res = requests.post(
    "https://kopik.io/api/v1/bases/code-du-travail-conges-x7k2/query",
    headers={
        "Authorization": f"Bearer {os.environ['KOPIK_API_KEY']}",
        "x-kopik-locale": "fr",
    },
    json={"question": "Combien de jours de congé pour un mariage ?", "mode": "answer"},
    timeout=60,
)
data = res.json()
if not res.ok:
    # data["code"] is stable: branch on it (e.g. "insufficient_credit", "rate_limited").
    raise RuntimeError(f"Kopik {res.status_code} {data['code']}: {data['error']}")

print(data["answer"])
for p in data["passages"]:
    print(f"[{p['n']}] {p['document']}")
print(f"Coût: €{data['costCents'] / 100:.2f} · solde: €{data['balanceCents'] / 100:.2f}")

Une réponse peut prendre une vingtaine de secondes : prévoyez un délai d'attente d'au moins 60 secondes, et réessayez après une pause en cas de 429 (rate_limited).

Prêt à brancher une base ?

Créez une clé et rechargez votre crédit, ou commencez par une base privée à vous, gratuite à interroger.

Créer une clé API