API de máquina do fornecedor
A API de máquinas do marketplace do fornecedor: gere uma chave sk-sup-… no painel, chame cada endpoint com Authorization: Bearer, cadastre conexões em lotes e leia conexões, ofertas, alterações de preço, ganhos e estatísticas.
O painel do fornecedor tem uma interface para máquinas: um fornecedor pode cadastrar contas em massa e ler as próprias conexões, ofertas, preços, histórico de alterações de preço, ganhos e estatísticas a partir de um script, usando uma chave de API com escopo de fornecedor em vez de uma sessão do navegador.
Isso é aditivo. O cabinet do navegador não é alterado, e as rotas de máquina montam os mesmos payloads que as páginas do cabinet, portanto as duas interfaces não podem informar números diferentes.
Obter uma chave
As chaves de máquina são criadas e revogadas no painel de fornecedores. O token completo é exibido uma vez, na criação, e nunca é retornado novamente.
- Abra o painel do fornecedor e localize a seção Machine API keys.
- Dê um rótulo à chave (opcional) e pressione criar.
- Copie o token imediatamente. Ele começa com
sk-sup-. - Armazene-a em um gerenciador de segredos ou em uma variável de ambiente. Nunca faça commit dela nem a envie em uma mensagem de suporte.
Endpoints de gerenciamento do Cabinet
Estas rotas usam a sessão do cabinet ou o token de rastreamento. Elas deliberadamente não aceitam uma chave de máquina, para que uma chave de máquina vazada não possa criar nem revogar outras chaves.
| Parâmetro | Tipo | Descrição |
|---|---|---|
GET /api/marketplace/suppliers/me/api-keys | list | Liste as chaves: id, label, prefix, active, lastUsedAt, createdAt. Nunca o token nem o hash dele. |
POST /api/marketplace/suppliers/me/api-keys | mint | Corpo { "label"?: string }. Retorna { "key": "sk-sup-…", "apiKey": { … } } — a única ocasião em que o token aparece. |
DELETE /api/marketplace/suppliers/me/api-keys/{id} | revoke | Revoga uma chave. 404 quando o id não pertence ao solicitante. |
Autenticação
Cada rota de máquina exige a chave do fornecedor como um token bearer:
Authorization: Bearer sk-sup-<64 hex>curl https://getvibeapi.com/api/marketplace/suppliers/api/v1/connections \
-H "Authorization: Bearer $SUPPLIER_API_KEY"Uma solicitação resolve a chave para exatamente um fornecedor, e cada consulta é filtrada por esse id. A revogação é limitada pelo id da chave e pelo proprietário, portanto um fornecedor não pode revogar a chave de outro fornecedor. Nunca registre nem transmita a chave.
401, para que o chamador não consiga distinguir os casos. Envie a chave somente por HTTPS.Endpoints de leitura
Todos são GET, autenticados com chave de API e limitados ao fornecedor autenticado. Os valores monetários em micro-USD são retornados como strings; as contagens de tokens são números.
Conexões
As contas conectadas do fornecedor, cada uma com o que ganhou (apenas valores a pagar).
{
"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"
}
]
}Ofertas
As ofertas do fornecedor com os preços atuais e a porcentagem atual em relação ao cartão oficial.
{
"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
}
]
}Histórico de alterações de preço
O registro de alterações de preço de uma das próprias ofertas do fornecedor: alterações planejadas, aplicadas e canceladas. Uma oferta pertencente a outro fornecedor responde 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
}
]
}Estatísticas
A mesma estrutura exibida pela página de estatísticas do painel: totals, uma série de daily de 14 dias e uma divisão byOffer por oferta.
{
"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 }
]
}Ganhos
Até 500 tentativas de rota recentes elegíveis para liquidação, da mais nova para a mais antiga.
{
"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"
}
]
}Criar conexões
Crie uma conta ou um pacote completo a partir de uma credencial que você já possui, sem uma ida e volta pelo OAuth do navegador. O corpo é um item, um envelope { "items": [ … ] }, ou uma matriz simples. Os três são normalizados para o mesmo resultado por item. O caminho anterior /api/marketplace/suppliers/api/v1/connections/batch é um alias do mesmo handler.
Formatos de credenciais
Cada item identifica o pool com provider (o nome legível do pool, por exemplo, codex ou claude-code) e contém exatamente um formato de credencial:
| Parâmetro | Tipo | Descrição |
|---|---|---|
codexAuthJson | codex-bundle | O ~/.codex/auth.json do Codex CLI colado literalmente: auth_mode, tokens.{id_token,access_token,refresh_token,account_id}, _meta.{plan_type,email}. |
accessToken + refreshToken | claude-tokens | O token de acesso do Claude Code (sk-ant-oat01-…) e seu token de atualização. |
refreshToken | antigravity-refresh | Um token de atualização do Antigravity. |
apiKey | api-key | Uma chave de API de assinatura pronta. |
bindToken + oauthCode | oauth-code | O resultado do OAuth do fluxo no navegador, quando você o usou em vez de colar um bundle. |
Cada item contém um proxy de saída funcional, e não existe conexão sem proxy. Envie seu próprio proxy, ou um proxyCountry para dar preferência a um dos nossos; não envie nenhum e o servidor atribuirá e comprovará um dos próprios antes de qualquer solicitação ao fornecedor. Se nenhum proxy do pool puder ser comprovado, o item será recusado como proxy_unavailable. externalId é devolvido sem alterações para correlação.
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 — um proxy próprio e um proxy de pool de países:
[
{
"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 por item e não grava nada novo. Tente novamente cada item com falha do pacote individualmente.Sucesso parcial é o contrato
Cada item é comprovado junto ao fornecedor e registrado individualmente. Uma linha inválida nunca faz o lote falhar, e um item só é reportado ok: true depois que sua linha de conexão é confirmada.
{
"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"
}
]
}Códigos de recusa por item
| Parâmetro | Tipo | Descrição |
|---|---|---|
invalid_credential | code | O fornecedor rejeitou o formato ou o valor da credencial. |
connection_type_unavailable | code | Esse tipo de conexão ainda não está disponível. |
subscription_product_unavailable | code | O produto de assinatura nomeado não é oferecido. |
provider_unavailable | code | O provedor selecionado não está disponível. |
bind_session_invalid | code | A sessão do OAuth expirou ou não correspondeu. |
proxy_required | code | O proxy resolvido não tinha uma URL utilizável. (Um item que não especifica nenhum proxy recebe um proxy em seu lugar.) |
proxy_unavailable | code | Não foi possível comprovar um proxy de pool para o país solicitado nem para qualquer país quando nenhum foi especificado. |
proxy_race_lost | code | Esse proxy acabou de ser assumido por outra conexão. |
probe_failed | code | O fornecedor rejeitou a credencial durante a verificação em tempo real. |
model_not_served | code | A conta não confirmou um modelo solicitado; os modelos recusados estão no array "models" do item. |
duplicate | code | A mesma impressão digital da credencial já está conectada. |
encryption_unavailable | code | A criptografia de credenciais não está configurada no projeto. |
internal_error | code | Um erro inesperado do servidor. Tente novamente o item individual mais tarde. |
Verificação prévia do proxy
Valide um proxy antes de entregar uma credencial: forneça seu próprio proxy ou um proxyCountry, e o servidor abrirá o mesmo túnel que usará para a conexão e alcançará um host neutro por meio dele. Isso é apenas uma verificação prévia — a chamada de criação executa a mesma verificação e recusa antes de trocar um token ou consultar o fornecedor, portanto um proxy com problemas nunca consome uma credencial.
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 com outcome: "proxy_failed"; um país sem proxy disponível no pool gratuito responde 409 com proxy_unavailable.OAuth no navegador (cabinet)
O próprio fluxo OAuth em duas etapas do cabinet, para quando você vincula uma conta em um navegador em vez de manter um bundle:
Corpo { "connectionType": "claude-code" | "codex-oauth" }. Retorna o authorizeUrl a ser aberto e o bindToken assinado que vincula o código à sessão PKCE. Nada é persistido.
Envia a concessão concluída — o bindToken mais o oauthCode e os mesmos campos offers / proxy de um item de criação. O proxy é comprovado antes da troca do código. Essas duas rotas usam a sessão do cabinet; uma chave de máquina não pode chamá-las (use POST /connections com bindToken + oauthCode).
Limites de taxa
| Parâmetro | Tipo | Descrição |
|---|---|---|
Create connections | limit | No máximo 25 itens por chamada. 20 chamadas por hora por fornecedor, além do limite de 120/hora por IP. Cada item é uma verificação de saída do fornecedor. |
Proxy pre-flight | limit | 30 chamadas por hora por IP. Cada chamada abre um túnel para um host neutro. |
Read endpoints | limit | 600 solicitações por hora por IP para a superfície de máquina compartilhada, a menos que uma rota defina seu próprio limite. |
Cabinet key management | limit | 120/hora por IP para listar chaves, 20/hora para criar, 60/hora para revogar. |
429 inclui Retry-After em segundos. Aguarde e tente novamente após esse atraso; reenviar a mesma credencial é recusado como duplicate pela impressão digital exclusiva da credencial.Respostas de erro
| Parâmetro | Tipo | Descrição |
|---|---|---|
401 | status | Chave de API ausente, desconhecida ou revogada. Uma mensagem fixa para que o chamador não consiga distinguir os casos. |
404 | status | O caminho não existe neste projeto (o marketplace não está habilitado aqui) ou a oferta endereçada pertence a outro fornecedor. |
429 | status | Limite de taxa. Retry-After é retornado pelo limitador compartilhado. |
400 | status | JSON malformado ou um lote acima do limite. O corpo identifica a entrada inválida. |
Uma descrição legível por máquina de cada endpoint faz parte do documento OpenAPI em /api/openapi. Aponte um gerador de clientes OpenAPI para ele para criar um cliente tipado.