API mesin pemasok
API machine marketplace supplier: buat kunci sk-sup-… di kabinet, panggil setiap endpoint dengan Authorization: Bearer, onboarding koneksi secara batch, dan baca koneksi, penawaran, perubahan harga, pendapatan, serta statistik.
Kabinet supplier memiliki permukaan machine: supplier dapat melakukan onboarding akun secara massal dan membaca koneksi, penawaran, harga, riwayat perubahan harga, pendapatan, dan statistik mereka sendiri dari skrip, menggunakan kunci API berskope supplier alih-alih sesi browser.
Ini bersifat aditif. Cabinet browser tidak berubah, dan rute machine menyusun payload yang sama seperti halaman cabinet, sehingga kedua permukaan tersebut tidak dapat melaporkan angka yang berbeda.
Dapatkan kunci
Kunci machine dibuat dan dicabut di kabinet supplier. Token lengkap hanya ditampilkan sekali, saat dibuat, dan tidak pernah dikembalikan lagi.
- Buka panel supplier dan temukan bagian Machine API keys.
- Beri label pada kunci (opsional) lalu tekan create.
- Segera salin token tersebut. Token dimulai dengan
sk-sup-. - Simpan di secret manager atau variabel lingkungan. Jangan pernah melakukan commit atau mengirimkannya dalam pesan dukungan.
Endpoint manajemen Cabinet
Rute-rute ini menggunakan sesi cabinet atau token pelacakan. Rute-rute ini sengaja tidak menerima machine key, sehingga machine key yang bocor tidak dapat membuat atau mencabut key lain.
| Parameter | Tipe | Deskripsi |
|---|---|---|
GET /api/marketplace/suppliers/me/api-keys | list | Kolom daftar: id, label, prefix, active, lastUsedAt, createdAt. Token atau hash-nya tidak pernah disertakan. |
POST /api/marketplace/suppliers/me/api-keys | mint | Body { "label"?: string }. Mengembalikan { "key": "sk-sup-…", "apiKey": { … } } — satu-satunya saat token tersebut muncul. |
DELETE /api/marketplace/suppliers/me/api-keys/{id} | revoke | Cabut satu key. 404 ketika id tidak dimiliki pemanggil. |
Autentikasi
Setiap rute mesin memerlukan key pemasok sebagai bearer token:
Authorization: Bearer sk-sup-<64 hex>curl https://getvibeapi.com/api/marketplace/suppliers/api/v1/connections \
-H "Authorization: Bearer $SUPPLIER_API_KEY"Sebuah permintaan memetakan kunci ke tepat satu supplier, dan setiap kueri difilter berdasarkan id tersebut. Pencabutan dibatasi oleh id kunci sekaligus pemiliknya, sehingga seorang supplier tidak dapat mencabut kunci supplier lain. Jangan pernah mencatat atau mengirimkan kunci tersebut.
401 yang tetap, sehingga pemanggil tidak dapat membedakan kasus-kasus tersebut. Kirim key hanya melalui HTTPS.Endpoint baca
Semuanya adalah GET, diautentikasi dengan API key dan dibatasi pada cakupan supplier yang terautentikasi. Nilai uang dalam micro-USD dikembalikan sebagai string; jumlah token berupa angka.
Koneksi
Akun terhubung milik supplier, masing-masing dengan jumlah yang telah diperolehnya (hanya yang dapat dibayarkan).
{
"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"
}
]
}Penawaran
Penawaran milik supplier dengan harga saat ini dan persentase kartu resmi secara live.
{
"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
}
]
}Riwayat perubahan harga
Buku besar perubahan harga untuk salah satu penawaran milik supplier itu sendiri: perubahan yang direncanakan, diterapkan, dan dibatalkan. Penawaran milik supplier lain dijawab dengan 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
}
]
}Statistik
Bentuk yang sama seperti yang ditampilkan halaman statistik kabinet: totals, deret daily 14 hari, dan rincian per penawaran byOffer.
{
"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 }
]
}Pendapatan
Hingga 500 percobaan rute terbaru yang memenuhi syarat penyelesaian, terbaru lebih dulu.
{
"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"
}
]
}Buat koneksi
Buat satu akun atau satu paket dari kredensial yang sudah Anda miliki — tanpa OAuth round-trip di browser. Body-nya berupa satu item, envelope { "items": [ … ] }, atau array langsung. Ketiganya dinormalisasi ke hasil per-item yang sama. Path /api/marketplace/suppliers/api/v1/connections/batch yang lebih lama adalah alias dari handler yang sama.
Bentuk kredensial
Setiap item menamai pool dengan provider (nama pool yang dapat dibaca, mis. codex atau claude-code) dan membawa tepat satu bentuk kredensial:
| Parameter | Tipe | Deskripsi |
|---|---|---|
codexAuthJson | codex-bundle | ~/.codex/auth.json dari Codex CLI yang ditempelkan apa adanya: auth_mode, tokens.{id_token,access_token,refresh_token,account_id}, _meta.{plan_type,email}. |
accessToken + refreshToken | claude-tokens | Token akses Claude Code (sk-ant-oat01-…) dan token refresh-nya. |
refreshToken | antigravity-refresh | Refresh token Antigravity. |
apiKey | api-key | Kunci API langganan yang siap pakai. |
bindToken + oauthCode | oauth-code | Hasil OAuth dari alur browser, ketika Anda menggunakannya alih-alih bundle yang ditempelkan. |
Setiap item membawa proxy keluar yang berfungsi, dan tidak ada koneksi tanpa proxy. Berikan proxy Anda sendiri, atau proxyCountry untuk memilih salah satu milik kami; jika tidak memberikan keduanya, server menetapkan dan membuktikan salah satu miliknya sebelum permintaan vendor apa pun. Jika tidak ada proxy pool yang dapat dibuktikan, item ditolak sebagai proxy_unavailable. externalId dikembalikan tanpa diubah untuk korelasi.
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 — satu proxy milik sendiri dan satu proxy country-pool:
[
{
"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 per item dan tidak menulis apa pun yang baru. Ulangi item paket yang gagal satu per satu.Keberhasilan sebagian adalah kontraknya
Setiap item dibuktikan terhadap vendor dan dicatat secara terpisah. Satu baris bermasalah tidak pernah menggagalkan seluruh batch, dan sebuah item dilaporkan ok: true hanya setelah baris koneksinya di-commit.
{
"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"
}
]
}Kode penolakan per item
| Parameter | Tipe | Deskripsi |
|---|---|---|
invalid_credential | code | Vendor menolak bentuk atau nilai kredensial tersebut. |
connection_type_unavailable | code | Jenis koneksi itu belum tersedia. |
subscription_product_unavailable | code | Produk langganan bernama tersebut tidak ditawarkan. |
provider_unavailable | code | Provider yang dipilih tidak tersedia. |
bind_session_invalid | code | Sesi OAuth telah kedaluwarsa atau tidak cocok. |
proxy_required | code | Proxy yang telah diresolusi tidak memiliki URL yang dapat digunakan. (Item yang tidak menyebutkan proxy apa pun akan diberi satu proxy.) |
proxy_unavailable | code | Tidak ada proxy pool yang dapat dibuktikan untuk negara yang diminta, atau untuk negara mana pun saat tidak ada negara yang disebutkan. |
proxy_race_lost | code | Proxy itu baru saja diambil oleh koneksi lain. |
probe_failed | code | Vendor menolak kredensial tersebut selama probe live. |
model_not_served | code | Akun tidak mengonfirmasi model yang diminta; model yang ditolak ada di array "models" pada item tersebut. |
duplicate | code | Fingerprint kredensial yang sama sudah terhubung. |
encryption_unavailable | code | Enkripsi kredensial belum dikonfigurasi pada project. |
internal_error | code | Error server yang tidak terduga. Coba lagi item tunggal tersebut nanti. |
Pre-flight proxy
Buktikan proxy sebelum Anda menyerahkan kredensial: berikan proxy atau proxyCountry milik Anda sendiri dan server akan membuka tunnel yang sama dengan yang akan dipakainya untuk koneksi tersebut lalu menjangkau host netral melaluinya. Ini hanya pre-flight — panggilan create menjalankan pemeriksaan yang identik dan menolak sebelum menukar token atau memeriksa vendor, sehingga proxy yang rusak tidak pernah memakan biaya kredensial.
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 dengan outcome: "proxy_failed"; negara tanpa proxy pool gratis menjawab 409 dengan proxy_unavailable.OAuth browser (kabinet)
Alur OAuth dua langkah milik cabinet itu sendiri, untuk saat Anda menautkan akun di browser alih-alih memegang bundle:
Body { "connectionType": "claude-code" | "codex-oauth" }. Mengembalikan authorizeUrl untuk dibuka dan bindToken bertanda tangan yang mengikat kode ke sesi PKCE. Tidak ada yang disimpan.
Mengirimkan grant yang telah selesai — bindToken beserta oauthCode dan field offers / proxy yang sama seperti item create. Proxy dibuktikan sebelum kode ditukar. Kedua rute ini menggunakan sesi cabinet; kunci mesin tidak dapat memanggilnya (gunakan POST /connections dengan bindToken + oauthCode sebagai gantinya).
Batas rate
| Parameter | Tipe | Deskripsi |
|---|---|---|
Create connections | limit | Maksimal 25 item per panggilan. 20 panggilan per jam per supplier, di atas batas 120/jam per IP. Setiap item merupakan probe vendor ke luar. |
Proxy pre-flight | limit | 30 panggilan per jam per IP. Setiap panggilan membuka satu tunnel ke host netral. |
Read endpoints | limit | 600 permintaan per jam per IP untuk permukaan mesin bersama kecuali sebuah route menetapkan batasnya sendiri. |
Cabinet key management | limit | 120/jam per IP untuk menampilkan daftar key, 20/jam untuk membuat, 60/jam untuk mencabut. |
429 membawa Retry-After dalam satuan detik. Back off dan coba lagi setelah jeda tersebut; mengirim ulang kredensial yang sama akan ditolak sebagai duplicate oleh sidik jari kredensial yang unik.Respons error
| Parameter | Tipe | Deskripsi |
|---|---|---|
401 | status | Kunci API tidak ada, tidak dikenal, atau dicabut. Satu pesan tetap, sehingga pemanggil tidak dapat membedakan kasus-kasusnya. |
404 | status | Path tersebut tidak ada pada proyek ini (marketplace tidak diaktifkan di sini), atau penawaran yang dituju milik pemasok lain. |
429 | status | Rate limit. Retry-After dikembalikan oleh limiter bersama. |
400 | status | JSON tidak valid atau batch melebihi batas. Isi body menyebutkan input yang tidak valid. |
Deskripsi setiap endpoint yang dapat dibaca mesin merupakan bagian dari dokumen OpenAPI di /api/openapi. Arahkan generator klien OpenAPI ke sana untuk membangun klien bertipe.