Authentification
Deux identités, qui ne sont pas interchangeables.
La clé d'usage
C'est celle des intégrations. Elle est stockée en base, n'expire pas par défaut, et voyage dans l'en-tête Authorization: Bearer.
curl "$SPAVIK_BASE_URL/v1/models" -H "Authorization: Bearer sk-spv-api-..."L'API l'accepte aussi dans X-API-Key. Les deux formes sont équivalentes ; les bibliothèques utilisent la première.
| Préfixe | Nature | Peut prédire |
|---|---|---|
sk-spv-api- | Clé d'usage | oui |
sk-spv-admin- | Clé d'administration | non |
Les clés émises avant septembre 2026 commençaient par ssk-. Elles ne sont plus reconnues : créez une nouvelle clé depuis votre espace de travail.
Une clé d'administration ne peut pas prédire : elle reçoit ADMIN_KEY_CANNOT_PREDICT. Et une clé d'usage ne peut pas en créer d'autres.
La session web
C'est celle des interfaces. Un lien de connexion part par courriel, s'échange contre une paire de jetons, et le jeton d'accès voyage dans Authorization: Bearer.
curl -X POST "$SPAVIK_BASE_URL/v1/auth/magic-link/request" \
-H 'Content-Type: application/json' -d '{"email":"vous@exemple.fr"}'Le lien et le code partent uniquement par courriel, jamais dans la réponse. C'est ce qui empêche un tiers capable de déclencher l'envoi d'ouvrir la session à votre place.
Le jeton d'accès a une durée de vie courte. Une application qui tourne longtemps doit le renouveler en cours de route, avec POST /v1/auth/refresh, sans redemander de lien.
Le jeton de rafraîchissement ne sert qu'une fois
Le rejouer signale qu'une copie circule : l'API révoque alors toute la famille de jetons du compte. Enchaînez vos renouvellements les uns après les autres, sans les lancer en parallèle depuis plusieurs requêtes.
Le cloisonnement se fait par route, pas par en-tête
Une clé d'usage ouvre les routes du moteur et de l'usage. Elle n'ouvre ni les routes de compte, qui exigent une session web, ni les routes d'administration, qui exigent une clé d'administration. L'API le dit clairement plutôt que de laisser deviner.
| Ce que vous présentez | Où | Réponse |
|---|---|---|
| Une clé d'usage valide | /v1/models, /v1/forecast, /v1/usage | 200, ça passe |
| Une clé d'usage valide | /v1/auth/me et les routes de compte | 401 AUTH_REQUIRED, il faut une session web |
| Une clé d'usage valide | /v1/api-keys, /v1/webhooks | 403 ADMIN_KEY_REQUIRED |
| Une clé inconnue | n'importe où | 401 API_KEY_INVALID |
| Un jeton d'accès expiré | n'importe où | 401 TOKEN_INVALID |
Changer de clé sans interruption
POST /v1/api-keys/{keyId}/rotate crée une clé jumelle et fixe une date de fin à l'ancienne, sept jours plus tard par défaut. Les deux fonctionnent le temps de la migration. Avec grace_days: 0, l'ancienne est révoquée immédiatement, ce qu'il faut faire si le secret a fuité.