Skip to content

3PI Partner API Reference

Base URL: https://api.vell.ai/api/v1

All endpoints require authentication via Bearer token. Partner management endpoints require Owner or Admin role. Usage endpoints are also accessible to the partner themselves.


Partner management

List partners

List all 3PI partners for your team.

GET /3pi-partners

Response:

{
  "data": [
    {
      "id": 42,
      "organization": "Acme Marketplace",
      "role": "partner_3pi",
      "status": "active",
      "sandbox_mode": true,
      "capabilities": ["mcp_access", "key_management", "usage_metrics"],
      "active_keys_count": 2,
      "last_api_access_at": "2026-03-15T13:45:00Z",
      "created_at": "2026-03-01T10:00:00Z"
    }
  ]
}

Create partner

Onboard a new 3PI partner. A default API key is auto-generated.

POST /3pi-partners

Request body:

Field Type Required Description
organization_name string Yes Partner organization name (max 255 chars)
capabilities string[] No Capability slugs to assign
sandbox boolean No Start in sandbox mode (default: true)

Request:

{
  "organization_name": "Acme Marketplace",
  "capabilities": ["mcp_access", "key_management", "usage_metrics", "webhooks", "sandbox"],
  "sandbox": true
}

Response 201 Created:

{
  "data": {
    "id": 42,
    "organization": "Acme Marketplace",
    "role": "partner_3pi",
    "status": "active",
    "sandbox_mode": true,
    "capabilities": ["mcp_access", "key_management", "usage_metrics", "webhooks", "sandbox"],
    "active_keys_count": 1,
    "created_at": "2026-03-15T10:30:00Z"
  },
  "api_key": {
    "id": 1,
    "name": "Default Key",
    "prefix": "vp3_a1b2c3d4",
    "plaintext": "vp3_a1b2c3d4e5f6...",
    "warning": "Store this key securely. It will not be shown again."
  }
}

Owner only

Only team Owners can create 3PI partners. Admins and other roles receive 403 Forbidden.


Get partner

Retrieve details for a specific partner.

GET /3pi-partners/{id}

Path parameters:

Parameter Type Description
id integer Partner ID

Response:

{
  "data": {
    "id": 42,
    "organization": "Acme Marketplace",
    "role": "partner_3pi",
    "status": "active",
    "sandbox_mode": false,
    "capabilities": ["mcp_access", "key_management", "usage_metrics"],
    "active_keys_count": 3,
    "last_api_access_at": "2026-03-15T13:45:00Z",
    "joined_at": "2026-03-01T10:00:00Z",
    "created_at": "2026-03-01T10:00:00Z"
  }
}

Toggle sandbox mode

Switch a partner between sandbox and production mode.

POST /3pi-partners/{id}/toggle-sandbox

Response:

{
  "data": {
    "id": 42,
    "sandbox_mode": false
  },
  "message": "Sandbox mode disabled — partner is now in production."
}

See the Sandbox Guide for details on how sandbox mode affects API behavior.


Deactivate partner

Deactivate a partner and revoke all their API keys. This is a soft delete — the partner record is preserved for audit purposes.

DELETE /3pi-partners/{id}

Response:

{
  "message": "Partner deactivated and all API keys revoked."
}

Irreversible

Deactivation immediately revokes all active API keys. The partner will lose access to all Vellocity APIs. Contact support to reactivate.


API key management

List keys

List all API keys for a partner (active and revoked).

GET /3pi-partners/{partnerId}/keys

Response:

{
  "data": [
    {
      "id": 8,
      "name": "Production - Content Service",
      "prefix": "vp3_n3w0k3y1",
      "scoped_capabilities": ["ai_writer", "content_studio"],
      "allowed_ip_addresses": ["203.0.113.10"],
      "rate_limit_per_minute": 120,
      "daily_credit_limit": 5000,
      "is_active": true,
      "is_valid": true,
      "expires_at": null,
      "revoked_at": null,
      "last_used_at": "2026-03-15T13:45:00Z",
      "total_requests": 1247,
      "created_at": "2026-03-15T14:00:00Z"
    }
  ]
}

Create key

Create a new API key for a partner with optional scoping.

POST /3pi-partners/{partnerId}/keys

Request body:

Field Type Required Description
name string Yes Human-readable key name (max 255 chars)
scoped_capabilities string[] No Capability slugs to restrict. null = all
allowed_ip_addresses string[] No IP allowlist. null = any IP
rate_limit_per_minute integer No Requests per minute (default: 60, max: 10,000)
daily_credit_limit integer No Max daily credits. null = unlimited
expires_at datetime No Key expiration (ISO 8601). Must be in the future

Request:

{
  "name": "Co-Sell Service Key",
  "scoped_capabilities": ["cosell_matching", "cosell_analytics"],
  "rate_limit_per_minute": 300,
  "daily_credit_limit": 10000
}

Response 201 Created:

{
  "data": {
    "id": 9,
    "name": "Co-Sell Service Key",
    "prefix": "vp3_c0s3ll01",
    "scoped_capabilities": ["cosell_matching", "cosell_analytics"],
    "rate_limit_per_minute": 300,
    "daily_credit_limit": 10000,
    "is_active": true,
    "is_valid": true,
    "created_at": "2026-03-15T15:00:00Z"
  },
  "plaintext": "vp3_c0s3ll01...",
  "warning": "Store this key securely. It will not be shown again."
}

Revoke key

Permanently disable an API key.

POST /3pi-partners/{partnerId}/keys/{keyId}/revoke

Request body (optional):

{
  "reason": "Key compromised"
}

Response:

{
  "message": "API key revoked.",
  "data": {
    "id": 9,
    "is_active": false,
    "revoked_at": "2026-03-15T16:00:00Z",
    "revoked_reason": "Key compromised"
  }
}

Rotate key

Atomically revoke the current key and generate a new one with identical settings.

POST /3pi-partners/{partnerId}/keys/{keyId}/rotate

Response:

{
  "data": {
    "id": 10,
    "name": "Co-Sell Service Key",
    "prefix": "vp3_r0t4t3d1",
    "scoped_capabilities": ["cosell_matching", "cosell_analytics"],
    "rate_limit_per_minute": 300,
    "daily_credit_limit": 10000,
    "is_active": true,
    "is_valid": true,
    "created_at": "2026-03-15T17:00:00Z"
  },
  "plaintext": "vp3_r0t4t3d1...",
  "warning": "Store this key securely. It will not be shown again.",
  "revoked_key_id": 9
}

Usage & billing

Get usage summary

Retrieve usage metrics for a partner. Supports daily and monthly aggregation.

GET /3pi-partners/{partnerId}/usage

Query parameters:

Parameter Type Default Description
period string daily Aggregation period: daily or monthly
date date today For daily: specific date (YYYY-MM-DD)
year integer current For monthly: year
month integer current For monthly: month (1-12)
GET /3pi-partners/42/usage?period=daily&date=2026-03-15
{
  "data": {
    "date": "2026-03-15",
    "total_requests": 1247,
    "successful_requests": 1230,
    "failed_requests": 12,
    "rate_limited_requests": 5,
    "total_credits": 3850,
    "total_input_tokens": 524000,
    "total_output_tokens": 312000,
    "avg_response_time_ms": 1340,
    "by_capability": {
      "ai_writer": {"requests": 800, "credits": 2400},
      "marketplace_seo": {"requests": 300, "credits": 750},
      "cosell_matching": {"requests": 147, "credits": 700}
    }
  }
}
GET /3pi-partners/42/usage?period=monthly&year=2026&month=3
{
  "data": {
    "period": "2026-03",
    "total_requests": 18420,
    "total_credits": 52300,
    "total_input_tokens": 7240000,
    "total_output_tokens": 4180000,
    "unique_capabilities_used": 8,
    "daily_breakdown": [
      {"billing_date": "2026-03-01", "requests": 945, "credits": 2800},
      {"billing_date": "2026-03-02", "requests": 1102, "credits": 3100}
    ]
  }
}

Sandbox requests excluded

Usage summaries only include production requests. Sandbox requests are tracked separately and do not appear in billing summaries.


Error responses

All endpoints return consistent error responses:

{
  "error": "Description of what went wrong"
}

Or for validation errors:

{
  "errors": {
    "organization_name": ["The organization name field is required."],
    "capabilities.0": ["The selected capability is invalid."]
  }
}

HTTP status codes

Status Meaning
200 Success
201 Resource created
403 Forbidden — insufficient permissions or capability not allowed
404 Partner or key not found
422 Validation error
429 Rate limited or daily credit limit exceeded