Model Management

Upload, manage, and delete custom models through the Model Management API. This API requires an API key with the models scope enabled.

Overview

Note: Model Management API endpoints use the path /proj_ABC123/v1/models. Ensure your API key has the "Model Management" scope enabled in your dashboard settings.

The Model Management API allows you to:

  • List all models in your project
  • Retrieve details for a specific model
  • Update model metadata (description, architecture, quantization, and more)
  • Delete models you no longer need
  • Trigger model revalidation to re-extract metadata
  • View catalog information for shared models

For uploading models, see the Model Upload guide. For versioning, see Model Versioning.

List Project Models

GET/proj_ABC123/v1/models

Lists all models uploaded to your project.

curl
curl https://api.xerotier.ai/proj_ABC123/v1/models \ -H "Authorization: Bearer xero_myproject_your_api_key"
Python
import requests headers = {"Authorization": "Bearer xero_myproject_your_api_key"} response = requests.get( "https://api.xerotier.ai/proj_ABC123/v1/models", headers=headers ) for model in response.json()["models"]: print(f"{model['name']} ({model['status']})")
Node.js
const response = await fetch( "https://api.xerotier.ai/proj_ABC123/v1/models", { headers: { "Authorization": "Bearer xero_myproject_your_api_key" } } ); const data = await response.json(); for (const model of data.models) { console.log(`${model.name} (${model.status})`); }

Response

{ "models": [ { "id": "00000000-1111-0000-1111-000000000000", "name": "my-custom-model", "format": "safetensors", "sizeBytes": 4294967296, "status": "ready", "createdAt": "2026-01-15T10:30:00Z" } ] }

Get Model Details

GET/proj_ABC123/v1/models/{modelId}

Retrieves detailed information about a specific model. Pass ?extended=true to include additional metadata such as format, size, architecture, and catalog status.

curl
curl https://api.xerotier.ai/proj_ABC123/v1/models/00000000-1111-0000-1111-000000000000?extended=true \ -H "Authorization: Bearer xero_myproject_your_api_key"
Python
import requests MODEL_ID = "00000000-1111-0000-1111-000000000000" headers = {"Authorization": "Bearer xero_myproject_your_api_key"} response = requests.get( f"https://api.xerotier.ai/proj_ABC123/v1/models/{MODEL_ID}", params={"extended": "true"}, headers=headers ) model = response.json() print(f"{model['name']} - {model['status']}")
Node.js
const MODEL_ID = "00000000-1111-0000-1111-000000000000"; const response = await fetch( `https://api.xerotier.ai/proj_ABC123/v1/models/${MODEL_ID}?extended=true`, { headers: { "Authorization": "Bearer xero_myproject_your_api_key" } } ); const model = await response.json(); console.log(`${model.name} - ${model.status}`);

Response (standard)

{ "id": "00000000-1111-0000-1111-000000000000", "object": "model", "created": 1706123456, "owned_by": "my-project" }

Response (extended)

{ "id": "00000000-1111-0000-1111-000000000000", "object": "model", "created": 1706123456, "owned_by": "my-project", "name": "my-custom-model", "format": "safetensors", "size_bytes": 4294967296, "size_formatted": "4.00 GB", "status": "ready", "version": "1.0.0", "is_latest": true, "description": "A fine-tuned LLM for code generation", "architecture": "LlamaForCausalLM", "quantization": "awq", "context_length": 32768, "parameter_count": 7000000000, "workload_type": "chat", "is_shared": false, "catalog_role": null }

Update Model Metadata

PATCH/proj_ABC123/v1/models/{modelId}

Updates metadata fields on an existing model. All fields in the request body are optional -- only provided fields will be updated.

Request Body

Parameter Type Description
descriptionoptional string Description of the model
licenseoptional string License identifier (e.g., "Apache-2.0")
architectureoptional string Model architecture (e.g., "LlamaForCausalLM")
quantizationoptional string Quantization method. Must be a valid vLLM runtime method (e.g., "awq", "gptq", "squeezellm")
context_lengthoptional integer Maximum context length in tokens
parameter_countoptional integer Total number of model parameters
hidden_sizeoptional integer Hidden dimension size extracted from model config
num_layersoptional integer Number of transformer layers
vocab_sizeoptional integer Vocabulary size extracted from model config
workload_typeoptional string Workload type: chat, code, reasoning, embedding, or multilingual. Defaults to chat.
curl
curl -X PATCH https://api.xerotier.ai/proj_ABC123/v1/models/00000000-1111-0000-1111-000000000000 \ -H "Authorization: Bearer xero_myproject_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "description": "Fine-tuned for code generation tasks", "architecture": "LlamaForCausalLM", "context_length": 32768 }'
Python
import requests MODEL_ID = "00000000-1111-0000-1111-000000000000" headers = { "Authorization": "Bearer xero_myproject_your_api_key", "Content-Type": "application/json" } response = requests.patch( f"https://api.xerotier.ai/proj_ABC123/v1/models/{MODEL_ID}", headers=headers, json={ "description": "Fine-tuned for code generation tasks", "architecture": "LlamaForCausalLM", "context_length": 32768 } ) model = response.json() print(f"Updated: {model['name']}")
Node.js
const MODEL_ID = "00000000-1111-0000-1111-000000000000"; const response = await fetch( `https://api.xerotier.ai/proj_ABC123/v1/models/${MODEL_ID}`, { method: "PATCH", headers: { "Authorization": "Bearer xero_myproject_your_api_key", "Content-Type": "application/json" }, body: JSON.stringify({ description: "Fine-tuned for code generation tasks", architecture: "LlamaForCausalLM", context_length: 32768 }) } ); const model = await response.json(); console.log(`Updated: ${model.name}`);

Response

{ "id": "00000000-1111-0000-1111-000000000000", "object": "model", "created": 1706123456, "owned_by": "my-project", "name": "my-custom-model", "format": "safetensors", "size_bytes": 4294967296, "size_formatted": "4.00 GB", "status": "ready", "version": "1.0.0", "is_latest": true, "description": "Fine-tuned for code generation tasks", "architecture": "LlamaForCausalLM", "quantization": "native", "context_length": 32768, "parameter_count": null, "workload_type": "chat", "is_shared": false, "catalog_role": null }

Delete Model

DELETE/proj_ABC123/v1/models/{modelId}

Permanently deletes a model from your project. This action cannot be undone.

Cascade Deletion: Deleting a model also permanently deletes all associated endpoints, endpoint workers, and routing rules. This action cannot be undone.

Requirements

  • API key with models scope
  • Project ownership of the model
curl
curl -X DELETE https://api.xerotier.ai/proj_ABC123/v1/models/00000000-1111-0000-1111-000000000000 \ -H "Authorization: Bearer xero_myproject_your_api_key"
Python
import requests API_KEY = "xero_myproject_your_api_key" BASE_URL = "https://api.xerotier.ai/proj_ABC123/v1" MODEL_ID = "00000000-1111-0000-1111-000000000000" response = requests.delete( f"{BASE_URL}/models/{MODEL_ID}", headers={"Authorization": f"Bearer {API_KEY}"} ) if response.status_code == 200: print(f"Model {MODEL_ID} deleted successfully") else: print(f"Error: {response.json()}")
Node.js
const MODEL_ID = "00000000-1111-0000-1111-000000000000"; const response = await fetch( `https://api.xerotier.ai/proj_ABC123/v1/models/${MODEL_ID}`, { method: "DELETE", headers: { "Authorization": "Bearer xero_myproject_your_api_key" } } ); if (response.ok) { console.log(`Model ${MODEL_ID} deleted successfully`); } else { const error = await response.json(); console.log(`Error: ${JSON.stringify(error)}`); }

Response

{ "deleted": true, "modelId": "00000000-1111-0000-1111-000000000000" }

Revalidate Model

POST/proj_ABC123/v1/models/{modelId}/revalidate

Triggers re-validation of a model. The model must be in ready or error status. Validation runs asynchronously and the model status will change to validating while in progress.

curl
curl -X POST https://api.xerotier.ai/proj_ABC123/v1/models/00000000-1111-0000-1111-000000000000/revalidate \ -H "Authorization: Bearer xero_myproject_your_api_key"
Python
import requests MODEL_ID = "00000000-1111-0000-1111-000000000000" headers = {"Authorization": "Bearer xero_myproject_your_api_key"} response = requests.post( f"https://api.xerotier.ai/proj_ABC123/v1/models/{MODEL_ID}/revalidate", headers=headers ) result = response.json() print(f"Status: {result['status']} - {result['message']}")
Node.js
const MODEL_ID = "00000000-1111-0000-1111-000000000000"; const response = await fetch( `https://api.xerotier.ai/proj_ABC123/v1/models/${MODEL_ID}/revalidate`, { method: "POST", headers: { "Authorization": "Bearer xero_myproject_your_api_key" } } ); const result = await response.json(); console.log(`Status: ${result.status} - ${result.message}`);

Response

{ "id": "00000000-1111-0000-1111-000000000000", "status": "validating", "message": "Model validation queued" }

Get Catalog Info

GET/proj_ABC123/v1/models/{modelId}/catalog-info

Returns catalog information for a model that has been shared to the public catalog. Includes the catalog role, deployment count, and whether the model is available on shared agents. Returns 404 if the model is not in the catalog.

curl
curl https://api.xerotier.ai/proj_ABC123/v1/models/00000000-1111-0000-1111-000000000000/catalog-info \ -H "Authorization: Bearer xero_myproject_your_api_key"
Python
import requests MODEL_ID = "00000000-1111-0000-1111-000000000000" headers = {"Authorization": "Bearer xero_myproject_your_api_key"} response = requests.get( f"https://api.xerotier.ai/proj_ABC123/v1/models/{MODEL_ID}/catalog-info", headers=headers ) if response.status_code == 200: info = response.json() print(f"Role: {info['catalog_role']}, Deployments: {info['deployment_count']}") else: print("Model is not in the catalog")
Node.js
const MODEL_ID = "00000000-1111-0000-1111-000000000000"; const response = await fetch( `https://api.xerotier.ai/proj_ABC123/v1/models/${MODEL_ID}/catalog-info`, { headers: { "Authorization": "Bearer xero_myproject_your_api_key" } } ); if (response.ok) { const info = await response.json(); console.log(`Role: ${info.catalog_role}, Deployments: ${info.deployment_count}`); } else { console.log("Model is not in the catalog"); }

Response

{ "id": "00000000-1111-0000-1111-000000000000", "catalog_role": "deployable", "deployment_count": 5, "is_on_shared_agents": false, "is_public": true, "featured": false, "shared_at": "2026-01-15T10:30:00Z" }