SSpiderIQ
SSpiderIQ

Docs / api-reference/integrations

Integrations

20 endpoints from the published OpenAPI import.

GET/api/v1/brands/{brand_id}/integrations

List Integration Overview

Overview of all configured providers with aggregated stats for a brand.

Provider list, key counts, healthy counts, and daily_limit capacity come from api_integrations (the config).

Daily usage, last-used timestamp, today's spend, and this month's spend come from gate_request_logs (the v3.2.0 litellm.Router flow's source of truth). The legacy daily_count + cached_usage_* columns stayed zero because the v1 mark_usage callback that wrote them is no longer in the request path. See PR #664.

Groups strictly by provider_name and resolves the display label from provider_registry.PROVIDER_REGISTRYprovider_label rows are cosmetic-only and ignored (PR #657 fix for the Mistral duplicate).

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/brands/{brand_id}/integrations

Create Integration

Create a new API integration (vault key) for this brand.

Vault self-service: a human brand_admin/super_admin (session) OR the brand's own agent (PAT with the opt-in gate:vault:write scope) may add a key. The new row is stamped brands_id = brand_id; for a PAT, require_vault_writer has already verified the token owns brand_id, so it can only ever add a key to its own brand.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "provider_name": "string",
  "key_label": "string",
  "credentials": {},
  "daily_limit": 0,
  "minute_limit": 0,
  "is_primary": false,
  "country_code": "string",
  "spend_limit_amount": 0.0,
  "spend_limit_period": "string",
  "spend_limit_action": "string",
  "share_with_pool": false,
  "free_models_only": false,
  "priority": 0,
  "hourly_limit": 0,
  "token_daily_limit": 0,
  "token_monthly_limit": 0,
  "supports_embeddings": true,
  "usage_policy": "string",
  "allowed_activities": [
    "string"
  ],
  "allowed_consumers": [
    "string"
  ]
}'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"provider_name": "string", "key_label": "string", "credentials": {}, "daily_limit": 0, "minute_limit": 0, "is_primary": false, "country_code": "string", "spend_limit_amount": 0.0, "spend_limit_period": "string", "spend_limit_action": "string", "share_with_pool": false, "free_models_only": false, "priority": 0, "hourly_limit": 0, "token_daily_limit": 0, "token_monthly_limit": 0, "supports_embeddings": true, "usage_policy": "string", "allowed_activities": ["string"], "allowed_consumers": ["string"]},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"provider_name": "string", "key_label": "string", "credentials": {}, "daily_limit": 0, "minute_limit": 0, "is_primary": false, "country_code": "string", "spend_limit_amount": 0.0, "spend_limit_period": "string", "spend_limit_action": "string", "share_with_pool": false, "free_models_only": false, "priority": 0, "hourly_limit": 0, "token_daily_limit": 0, "token_monthly_limit": 0, "supports_embeddings": true, "usage_policy": "string", "allowed_activities": ["string"], "allowed_consumers": ["string"]})
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"provider_name": "string", "key_label": "string", "credentials": {}, "daily_limit": 0, "minute_limit": 0, "is_primary": false, "country_code": "string", "spend_limit_amount": 0.0, "spend_limit_period": "string", "spend_limit_action": "string", "share_with_pool": false, "free_models_only": false, "priority": 0, "hourly_limit": 0, "token_daily_limit": 0, "token_monthly_limit": 0, "supports_embeddings": true, "usage_policy": "string", "allowed_activities": ["string"], "allowed_consumers": ["string"]}`)
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/brands/{brand_id}/integrations/providers

List Provider Templates

List available provider templates with field schemas.

Each template carries its provider→ToS classification (VAULT.1 2c.1, dark) so the add-key UI can pre-forbid ToS-locked activity toggles before a key even exists. Fail-closed: a provider with no confirmed classification reports all 6 activities forbidden with classification_status='unclassified'.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/providers' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/providers",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/providers", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/providers", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/brands/{brand_id}/gate/subscription-tiers

List Subscription Tiers

List curated subscription packages (provider_subscription_tiers) for the vault key editor's package dropdown (VAULT subscription-billing, D2).

Brand-scoped read (any brand member) — the catalog is global/curated, not brand data, but the route is brand-owned for a consistent auth surface with the rest of the vault. Fail-soft: an absent table (pre-mig-447) returns [].

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
providerqueryanyfalseFilter to one provider's packages (e.g. minimax)
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/brands/{brand_id}/gate/subscription-tiers' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/brands/{brand_id}/gate/subscription-tiers",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/gate/subscription-tiers", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/brands/{brand_id}/gate/subscription-tiers", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/brands/{brand_id}/integrations/all

List Integrations

List all integration keys for a brand, optionally filtered by provider.

Each row carries log-derived stats (requests_24h, spend_today, spend_month, last_used_at) aggregated from gate_request_logs joined on integration_id. Legacy daily_count / cached_usage_* / last_used_at columns stay populated for backward compatibility but are stale — the v3.2.0 litellm.Router flow doesn't update them.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
provider_namequeryanyfalseFilter by provider name
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/all' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/all",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/all", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/all", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/brands/{brand_id}/integrations/{integration_id}

Get Integration

Get a single integration key detail.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
integration_idpathintegertrue
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
PATCH/api/v1/brands/{brand_id}/integrations/{integration_id}

Update Integration

Update an integration key.

Gated by require_vault_writer (VAULT.1 3.1): a brand_admin/super_admin session OR a gate:vault:write PAT that owns this brand. Brand ownership is doubly enforced — the dep's _pat_client_owns_brand check for PATs and the WHERE … AND brands_id = $2 fetch below (404 for a foreign key). The allowed_consumers ToS consumer-lock is additionally super-admin-only.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
integration_idpathintegertrue
Try it
Query

Examples

cURL
curl -X PATCH 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "key_label": "string",
  "credentials": {},
  "daily_limit": 0,
  "minute_limit": 0,
  "is_primary": true,
  "is_active": true,
  "country_code": "string",
  "spend_limit_amount": 0.0,
  "spend_limit_period": "string",
  "spend_limit_action": "string",
  "share_with_pool": true,
  "free_models_only": true,
  "supports_embeddings": true,
  "usage_policy": "string",
  "allowed_activities": [
    "string"
  ],
  "allowed_consumers": [
    "string"
  ],
  "billing_mode": "string",
  "subscription_tier": "string",
  "base_url": "string"
}'
Python
import httpx

resp = httpx.patch(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"key_label": "string", "credentials": {}, "daily_limit": 0, "minute_limit": 0, "is_primary": true, "is_active": true, "country_code": "string", "spend_limit_amount": 0.0, "spend_limit_period": "string", "spend_limit_action": "string", "share_with_pool": true, "free_models_only": true, "supports_embeddings": true, "usage_policy": "string", "allowed_activities": ["string"], "allowed_consumers": ["string"], "billing_mode": "string", "subscription_tier": "string", "base_url": "string"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}", {
  method: "PATCH",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"key_label": "string", "credentials": {}, "daily_limit": 0, "minute_limit": 0, "is_primary": true, "is_active": true, "country_code": "string", "spend_limit_amount": 0.0, "spend_limit_period": "string", "spend_limit_action": "string", "share_with_pool": true, "free_models_only": true, "supports_embeddings": true, "usage_policy": "string", "allowed_activities": ["string"], "allowed_consumers": ["string"], "billing_mode": "string", "subscription_tier": "string", "base_url": "string"})
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"key_label": "string", "credentials": {}, "daily_limit": 0, "minute_limit": 0, "is_primary": true, "is_active": true, "country_code": "string", "spend_limit_amount": 0.0, "spend_limit_period": "string", "spend_limit_action": "string", "share_with_pool": true, "free_models_only": true, "supports_embeddings": true, "usage_policy": "string", "allowed_activities": ["string"], "allowed_consumers": ["string"], "billing_mode": "string", "subscription_tier": "string", "base_url": "string"}`)
	req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
DELETE/api/v1/brands/{brand_id}/integrations/{integration_id}

Delete Integration

Delete an integration key. Brand admin only.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
integration_idpathintegertrue
Try it
Query

Examples

cURL
curl -X DELETE 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.delete(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}", {
  method: "DELETE",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/brands/{brand_id}/integrations/oauth/self/start

Self Oauth Start

Begin a self-serve OAuth connect for the caller's own new subscription key.

Brand is the validated path segment (require_brand_owner); no invite needed. Only oauth_pkce subscription providers (Claude Code / Codex / Gemini CLI) — those use the provider's OWN registered redirect (localhost:1455 / claude.com), so there is no app.spideriq.ai callback to register. Mirrors contribute_oauth_start (contribute.py) minus the invite binding.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/oauth/self/start' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "provider": "string"
}'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/oauth/self/start",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"provider": "string"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/oauth/self/start", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"provider": "string"})
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"provider": "string"}`)
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/oauth/self/start", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/brands/{brand_id}/integrations/oauth/self/callback

Self Oauth Callback

Complete a self-serve OAuth connect: exchange the pasted code for tokens and vault them for THIS brand. Clones contribute_oauth_callback's exchange + INSERT + INJECT-only de-pool; brand comes from the path, not an invite.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/oauth/self/callback' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "provider": "string",
  "code": "string",
  "state": "string"
}'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/oauth/self/callback",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"provider": "string", "code": "string", "state": "string"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/oauth/self/callback", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"provider": "string", "code": "string", "state": "string"})
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"provider": "string", "code": "string", "state": "string"}`)
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/oauth/self/callback", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/brands/{brand_id}/integrations/{integration_id}/reset-usage

Reset Integration Usage

Reset daily and minute usage counters. Brand admin only.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
integration_idpathintegertrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/reset-usage' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/reset-usage",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/reset-usage", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/reset-usage", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/brands/{brand_id}/integrations/{integration_id}/reauth

Request Integration Reauth

Issue a single-use re-auth link for one of this brand's vault credentials and email it to the key's contributor. The link lets them re-login / paste a fresh key and UPDATE the same row in place (see app/api/v1/gate/reauth.py).

Guards:

  • non-super_admin callers must be a member of brand_id (403 otherwise),
  • the credential must belong to brand_id (404 otherwise) — a brand can never re-auth a pool / other-tenant key it doesn't own.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
integration_idpathintegertrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/reauth' \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "notify_contributor": false
}'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/reauth",
    headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
    json={"notify_contributor": false},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/reauth", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
  body: JSON.stringify({"notify_contributor": false})
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
	"strings"
)

func main() {
	body := strings.NewReader(`{"notify_contributor": false}`)
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/reauth", body)
	req.Header.Set("Authorization", "Bearer <token>")
	req.Header.Set("Content-Type", "application/json")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/brands/{brand_id}/integrations/spend/provider/{provider_name}

Get Provider Spend Overview

Get aggregated spend overview for a provider.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
provider_namepathstringtrue
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/spend/provider/{provider_name}' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/spend/provider/{provider_name}",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/spend/provider/{provider_name}", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/spend/provider/{provider_name}", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/brands/{brand_id}/integrations/{integration_id}/spend

Get Integration Spend

Get spend data for a specific integration with history.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
integration_idpathintegertrue
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/spend' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/spend",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/spend", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/spend", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/brands/{brand_id}/integrations/{integration_id}/test

Test Integration Connection

Test if an API key is working by making a lightweight API call.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
integration_idpathintegertrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/test' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/test",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/test", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/test", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/brands/{brand_id}/integrations/{integration_id}/sync-billing

Sync Integration Billing

Trigger billing sync for an integration using its billing adapter.

Parameters

NameInTypeRequiredDescription
brand_idpathintegertrue
integration_idpathintegertrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/sync-billing' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/sync-billing",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/sync-billing", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/brands/{brand_id}/integrations/{integration_id}/sync-billing", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
GET/api/v1/admin/integrations/pool/stats

Get Pool Stats

Get statistics for the shared key pool.

🔴 GUR-21 — reports the pool TWO ways, and the difference between them.

pool_integrations counts share_with_pool = TRUE, which is ONE clause of the seven-clause question the Router actually asks. On the live primary, 2026-08-25, this console showed 56 while the Router admitted 46 — nine deactivated mistral keys and integration 107 (opvs, is_pool_eligible = FALSE). An operator sizing the fleet off 56 was sizing it off invisible capacity.

admitted_by_router is the Router's own predicate, rendered from services.gate.pool_admission — the same tuple FETCH_HEALTHY_KEYS_SQL builds its WHERE block from, so the two cannot drift apart again silently. exclusion_reasons breaks the gap down by cause, one reason per key, and is zero-filled so an absent reason reads as zero rather than as a missing field.

Both numbers are published deliberately. A corrected single number would hide the flagged-but-not-admitted condition, which is the thing worth seeing.

⚠️ total_daily_used / capacity_used_percent are daily_count-derived and measure the LEGACY Path-A selection path only. get_next_available_key increments the counter; the litellm Router does not. Measured 2026-08-25: gate_request_logs carries 9,326 gateway requests for the day against SUM(daily_count) = 2,276, and 13 of the 14 keys that actually served today read daily_count = 0. Do not read this percentage as gateway utilisation — /admin/gate/pool-utilization derives rotation from the LOGS and is the number that answers that question.

🔴 The column has been called "dead" twice in planning notes and "live" once, and each claim was true about a different thing. It is a LIVE admission filter and ORDER BY tie-break in both Path-A queries (so it must not be dropped), and it is near-blind as a measurement of gateway traffic (so it must not be reported as one).

Try it

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/admin/integrations/pool/stats' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/admin/integrations/pool/stats",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/admin/integrations/pool/stats", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/admin/integrations/pool/stats", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
GET/api/v1/admin/integrations/pool

List Pool Integrations

List all pool integrations (share_with_pool=true). Admin only.

Parameters

NameInTypeRequiredDescription
provider_namequeryanyfalseFilter by provider name
only_availablequerybooleanfalseOnly show available keys
Try it
Query

Examples

cURL
curl -X GET 'https://spideriq.ai/api/v1/admin/integrations/pool' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.get(
    "https://spideriq.ai/api/v1/admin/integrations/pool",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/admin/integrations/pool", {
  method: "GET",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/admin/integrations/pool", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/admin/integrations/{integration_id}/reset-failures

Reset Integration Failures

Reset consecutive failures and set health to healthy. Admin only.

Parameters

NameInTypeRequiredDescription
integration_idpathintegertrue
Try it
Query

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/admin/integrations/{integration_id}/reset-failures' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/admin/integrations/{integration_id}/reset-failures",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/admin/integrations/{integration_id}/reset-failures", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/admin/integrations/{integration_id}/reset-failures", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response
422Validation Error
POST/api/v1/admin/integrations/reset-daily

Reset Daily Counters

Reset daily counters for all integrations. Admin only.

Try it

Examples

cURL
curl -X POST 'https://spideriq.ai/api/v1/admin/integrations/reset-daily' \
  -H 'Authorization: Bearer <token>'
Python
import httpx

resp = httpx.post(
    "https://spideriq.ai/api/v1/admin/integrations/reset-daily",
    headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())
JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/admin/integrations/reset-daily", {
  method: "POST",
  headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);
Go
package main

import (
	"net/http"
)

func main() {
	req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/admin/integrations/reset-daily", nil)
	req.Header.Set("Authorization", "Bearer <token>")
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()
}

Responses

StatusDescription
200Successful Response