API machine du fournisseur
L’API machine de la marketplace des fournisseurs : créez une clé sk-sup-… dans le cabinet, appelez chaque endpoint avec Authorization: Bearer, intégrez les connexions par lots et consultez les connexions, offres, changements de prix, revenus et statistiques.
Le cabinet du fournisseur dispose d’une interface machine : un fournisseur peut intégrer des comptes en masse et consulter leurs propres connexions, offres, prix, historique des changements de prix, revenus et statistiques depuis un script, à l’aide d’une clé API limitée au fournisseur plutôt que d’une session de navigateur.
Cela s’ajoute à l’existant. Le cabinet dans le navigateur reste inchangé et les routes machine assemblent les mêmes charges utiles que les pages du cabinet ; les deux interfaces ne peuvent donc pas afficher des chiffres différents.
Obtenir une clé
Les clés machine sont créées et révoquées dans le cabinet des fournisseurs. Le token complet est affiché une seule fois, lors de sa création, et n’est plus jamais renvoyé.
- Ouvrez l’espace fournisseur et trouvez la section Machine API keys.
- Donnez un libellé à la clé (facultatif), puis appuyez sur create.
- Copiez immédiatement le token. Il commence par
sk-sup-. - Stockez-la dans un gestionnaire de secrets ou une variable d’environnement. Ne la validez jamais dans le dépôt et ne l’envoyez jamais dans un message au support.
Points de terminaison de gestion des armoires
Ces routes utilisent la session du cabinet ou le jeton de suivi. Elles n’acceptent délibérément pas de clé machine, afin qu’une clé machine divulguée ne puisse pas créer ni révoquer d’autres clés.
| Paramètre | Type | Description |
|---|---|---|
GET /api/marketplace/suppliers/me/api-keys | list | Clés listées : id, label, prefix, active, lastUsedAt, createdAt. Jamais le token ni son hash. |
POST /api/marketplace/suppliers/me/api-keys | mint | Corps { "label"?: string }. Renvoie { "key": "sk-sup-…", "apiKey": { … } } — l’unique moment où le jeton apparaît. |
DELETE /api/marketplace/suppliers/me/api-keys/{id} | revoke | Révoque une clé. 404 lorsque l'id n'appartient pas à l'appelant. |
Authentification
Chaque route machine requiert la clé du fournisseur comme jeton bearer :
Authorization: Bearer sk-sup-<64 hex>curl https://getvibeapi.com/api/marketplace/suppliers/api/v1/connections \
-H "Authorization: Bearer $SUPPLIER_API_KEY"Une requête associe la clé à exactement un fournisseur, et chaque requête est filtrée par cet identifiant. La révocation est limitée à la fois par l’identifiant de la clé et par son propriétaire, de sorte qu’un fournisseur ne peut pas révoquer la clé d’un autre fournisseur. Ne consignez ni ne transmettez jamais la clé.
401 fixe, afin qu’un appelant ne puisse pas distinguer ces cas. Envoyez la clé uniquement via HTTPS.Points de terminaison de lecture
Tous sont des GET, authentifiés par clé API et associés au fournisseur authentifié. Les montants en micro-USD sont renvoyés sous forme de chaînes de caractères ; les décomptes de tokens sont des nombres.
Connexions
Les comptes connectés du fournisseur, chacun avec les revenus qu’il a générés (uniquement les montants payables).
{
"connections": [
{
"id": "…",
"connectionType": "subscription-api-key",
"subscriptionProductLabel": "…",
"verifiedEndpoint": "https://…",
"status": "ACTIVE",
"enabled": true,
"verificationState": "verified",
"verifiedBy": "…",
"label": "nightly-1",
"account": "…",
"verifiedModels": ["…"],
"servingModels": ["…"],
"lastVerifiedAt": "2026-09-18T09:00:00.000Z",
"proxy": "…",
"proxySource": "pool",
"proxyCountry": "de",
"proxyExpiresAt": "2026-10-18T09:00:00.000Z",
"proxyExpiryDays": 30,
"proxyLost": false,
"probedVia": "…",
"lastError": null,
"needsReauth": false,
"accountLimits": null,
"accountLimitsSource": null,
"accountLimitsCheckedAt": null,
"earnings": { "earnedMicros": "1250000", "requestCount": 42 },
"createdAt": "2026-09-01T09:00:00.000Z"
}
]
}Offres
Les offres du fournisseur avec les prix actuels et le pourcentage en temps réel de la carte officielle.
{
"offers": [
{
"id": "…",
"baseModel": "claude-opus-5",
"claimedModel": "claude-opus-5",
"providerLabel": "…",
"status": "ACTIVE",
"statusReason": null,
"inputMicrosPer1M": "1000000",
"outputMicrosPer1M": "2000000",
"cacheReadMicrosPer1M": null,
"blendedPctOfOfficial": "0.42",
"officialPrice": null,
"pctOfOfficial": 42,
"trafficTier": "…",
"cooldownUntil": null,
"cooldownReason": null,
"firstVerifiedAt": "2026-09-01T09:00:00.000Z",
"activatedAt": "2026-09-01T09:00:00.000Z",
"lastManualPriceChangeAt": null,
"maxConcurrentRequests": 8,
"servingEnabled": true
}
]
}Historique des changements de prix
Le registre des changements de prix pour l’une des propres offres du fournisseur : changements planifiés, appliqués et annulés. Une offre appartenant à un autre fournisseur répond 404.
{
"offerId": "…",
"schedules": [
{
"id": "…",
"offerId": "…",
"priceInUsd": "1.000000",
"priceOutUsd": "2.000000",
"effectiveFrom": "2026-10-01T00:00:00.000Z",
"createdAt": "2026-09-18T09:00:00.000Z",
"cancelledAt": null,
"appliedAt": null
}
]
}Statistiques
La même structure que celle affichée par la page des statistiques du cabinet : totals, une série daily sur 14 jours et une ventilation byOffer par offre.
{
"totals": {
"requests": 12000,
"successes": 11880,
"errors": 90,
"timeouts": 30,
"successRatePct": 99,
"promptTokens": 9000000,
"completionTokens": 4000000,
"cacheTokens": 2500000,
"sourceCostMicros": 12345678,
"avgLatencyMs": 812.4,
"p50LatencyMs": 640,
"p95LatencyMs": 2100
},
"daily": [
{ "date": "2026-09-05", "requests": 800, "successes": 795, "errors": 4, "promptTokens": 600000, "completionTokens": 250000, "sourceCostMicros": 900000 }
],
"byOffer": [
{ "offerId": "…", "baseModel": "claude-opus-5", "requests": 12000, "successRatePct": 99, "promptTokens": 9000000, "completionTokens": 4000000, "tokens": 13000000, "sourceCostMicros": 12345678, "hitRate": 0.28, "effTotal": 3.14, "rank": 1 }
]
}Revenus
Jusqu’à 500 tentatives de route récentes éligibles au règlement, de la plus récente à la plus ancienne.
{
"events": [
{
"id": "…",
"baseModel": "claude-opus-5",
"result": "SUCCESS",
"promptTokens": "1200",
"completionTokens": "800",
"paidMicros": "420000",
"settlementEligible": true,
"finishedAt": "2026-09-18T09:00:00.000Z",
"settlementStatus": "pending_or_settled"
}
]
}Créer des connexions
Créez un compte ou un ensemble complet à partir d’un identifiant que vous détenez déjà, sans parcours OAuth dans le navigateur. Le corps est un élément, une enveloppe { "items": [ … ] }, ou un tableau brut. Les trois formats sont normalisés vers le même résultat par élément. L’ancien chemin /api/marketplace/suppliers/api/v1/connections/batch est un alias du même gestionnaire.
Formats des identifiants
Chaque élément indique le pool avec provider (le nom lisible du pool, par ex. codex ou claude-code) et contient exactement un format d’identifiant :
| Paramètre | Type | Description |
|---|---|---|
codexAuthJson | codex-bundle | Le fichier ~/.codex/auth.json de Codex CLI collé tel quel : auth_mode, tokens.{id_token,access_token,refresh_token,account_id}, _meta.{plan_type,email}. |
accessToken + refreshToken | claude-tokens | Le jeton d’accès Claude Code (sk-ant-oat01-…) et son jeton d’actualisation. |
refreshToken | antigravity-refresh | Un token d’actualisation Antigravity. |
apiKey | api-key | Une clé API d’abonnement prête à l’emploi. |
bindToken + oauthCode | oauth-code | Le résultat OAuth issu du flux du navigateur, lorsque vous l’avez utilisé à la place d’un bundle collé. |
Chaque élément utilise un proxy de sortie fonctionnel, et aucune connexion sans proxy n’est possible. Transmettez votre propre proxy, ou un proxyCountry pour en privilégier un des nôtres ; n’en transmettez aucun et le serveur en attribuera et en vérifiera un lui-même avant toute requête auprès du fournisseur. Si aucun proxy du pool ne peut être vérifié, l’élément est refusé avec proxy_unavailable. externalId est renvoyé tel quel pour la corrélation.
curl https://getvibeapi.com/api/marketplace/suppliers/api/v1/connections \
-H "Authorization: Bearer $SUPPLIER_API_KEY" \
-H "Content-Type: application/json" \
--data @pack.jsonpack.json — un proxy propre et un proxy de pool de pays :
[
{
"externalId": "codex-1",
"provider": "codex",
"connectionLabel": "nightly-codex-1",
"codexAuthJson": "{\"auth_mode\":\"chatgpt\",\"tokens\":{\"id_token\":\"…\",\"access_token\":\"…\",\"refresh_token\":\"…\",\"account_id\":\"…\"},\"_meta\":{\"plan_type\":\"plus\",\"email\":\"…\"}}",
"proxy": { "scheme": "http", "host": "proxy.example.com", "port": 8899, "username": "u", "password": "p" },
"offers": [{ "baseModel": "deepseek-v4.1-flash", "inputMicrosPer1M": 1000000, "outputMicrosPer1M": 2000000 }]
},
{
"externalId": "claude-1",
"provider": "claude-code",
"connectionLabel": "nightly-claude-1",
"accessToken": "sk-ant-oat01-…",
"refreshToken": "sk-ant-ort01-…",
"proxyCountry": "de",
"offers": [{ "baseModel": "claude-opus-5", "inputMicrosPer1M": 1000000, "outputMicrosPer1M": 2000000 }]
}
]duplicate par élément et n’écrit rien de nouveau. Réessayez les éléments du pack ayant échoué un par un.Le succès partiel fait partie du contrat
Chaque élément est vérifié auprès du fournisseur et enregistré séparément. Une ligne incorrecte ne fait jamais échouer le lot, et un élément est signalé ok: true uniquement après la validation de sa ligne de connexion.
{
"supplierId": "…",
"accepted": 1,
"rejected": 1,
"results": [
{
"index": 0,
"externalId": "row-1",
"ok": true,
"connectionId": "…",
"connectionType": "subscription-api-key",
"verificationState": "verified",
"verifiedModels": ["…"],
"subscriptionProduct": "codebuddy-cn",
"verifiedEndpoint": "https://…",
"latencyMs": 210
},
{
"index": 1,
"externalId": "row-2",
"ok": false,
"code": "bind_session_invalid",
"error": "the authorization session expired or did not match"
}
]
}Codes de refus par élément
| Paramètre | Type | Description |
|---|---|---|
invalid_credential | code | Le fournisseur a rejeté le format ou la valeur de l’identifiant. |
connection_type_unavailable | code | Ce type de connexion n’est pas encore disponible. |
subscription_product_unavailable | code | Le produit d’abonnement indiqué n’est pas proposé. |
provider_unavailable | code | Le fournisseur sélectionné n’est pas disponible. |
bind_session_invalid | code | La session OAuth a expiré ou ne correspondait pas. |
proxy_required | code | Le proxy résolu ne disposait d’aucune URL utilisable. (Un élément qui ne nomme aucun proxy s’en voit attribuer un.) |
proxy_unavailable | code | Aucun proxy de pool n’a pu être confirmé pour le pays demandé, ni pour quelque pays que ce soit lorsqu’aucun pays n’a été indiqué. |
proxy_race_lost | code | Ce proxy vient d’être pris par une autre connexion. |
probe_failed | code | Le fournisseur a rejeté l’identifiant lors de la vérification en direct. |
model_not_served | code | Le compte n’a pas confirmé un modèle demandé ; les modèles refusés se trouvent dans le tableau "models" de l’élément. |
duplicate | code | La même empreinte d’identifiant est déjà connectée. |
encryption_unavailable | code | Le chiffrement des identifiants n’est pas configuré sur le projet. |
internal_error | code | Une erreur serveur inattendue. Réessayez l’élément unique ultérieurement. |
Vérification préalable du proxy
Vérifiez un proxy avant de transmettre un identifiant d’authentification : fournissez votre propre proxy ou un proxyCountry, et le serveur ouvre le même tunnel qu’il utilisera pour la connexion, puis atteint un hôte neutre par son intermédiaire. Il s’agit uniquement d’une vérification préalable : l’appel de création exécute le contrôle identique et refuse la requête avant d’échanger un jeton ou d’interroger le fournisseur, afin qu’un proxy défaillant ne consomme jamais d’identifiant d’authentification.
curl https://getvibeapi.com/api/marketplace/suppliers/proxy-check \
-H "Content-Type: application/json" \
-d '{ "proxy": { "scheme": "http", "host": "proxy.example.com", "port": 8899, "username": "u", "password": "p" } }'{ "ok": true, "outcome": "ok", "latencyMs": 42 }422 avec outcome: "proxy_failed" ; un pays sans proxy disponible dans le pool gratuit répond 409 avec proxy_unavailable.OAuth dans le navigateur (espace de gestion)
Le propre flux OAuth en deux étapes du cabinet, lorsque vous liez un compte dans un navigateur au lieu de détenir un bundle :
Corps { "connectionType": "claude-code" | "codex-oauth" }. Renvoie le authorizeUrl à ouvrir et le bindToken signé qui associe le code à la session PKCE. Rien n’est conservé.
Soumet la validation de l’autorisation terminée — le bindToken ainsi que les champs oauthCode et les mêmes champs offers / proxy que pour la création d’un élément. Le proxy est vérifié avant l’échange du code. Ces deux routes utilisent la session cabinet ; une clé machine ne peut pas les appeler (utilisez POST /connections avec bindToken + oauthCode à la place).
Limites de débit
| Paramètre | Type | Description |
|---|---|---|
Create connections | limit | 25 éléments maximum par appel. 20 appels par heure et par fournisseur, en plus d’une limite de 120/heure par adresse IP. Chaque élément constitue une vérification sortante auprès d’un fournisseur. |
Proxy pre-flight | limit | 30 appels par heure et par IP. Chaque appel ouvre un tunnel vers un hôte neutre. |
Read endpoints | limit | 600 requêtes par heure et par IP pour la surface de la machine partagée, sauf si une route définit sa propre limite. |
Cabinet key management | limit | 120/heure par IP pour lister les clés, 20/heure pour en créer, 60/heure pour les révoquer. |
429 contient Retry-After en secondes. Attendez ce délai avant de réessayer ; la nouvelle soumission du même identifiant est refusée comme duplicate par l’empreinte d’identifiant unique.Réponses d’erreur
| Paramètre | Type | Description |
|---|---|---|
401 | status | Clé API manquante, inconnue ou révoquée. Un message unique est utilisé afin qu’un appelant ne puisse pas distinguer les cas. |
404 | status | Le chemin n’existe pas dans ce projet (la marketplace n’y est pas activée), ou l’offre ciblée appartient à un autre fournisseur. |
429 | status | Limite de débit. Retry-After est renvoyé par le limiteur partagé. |
400 | status | JSON mal formé ou lot dépassant la limite. Le corps indique l’entrée non valide. |
Une description lisible par machine de chaque endpoint figure dans le document OpenAPI à l’adresse /api/openapi. Indiquez-la à un générateur de clients OpenAPI pour créer un client typé.