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 https://api.xerotier.ai/proj_ABC123/v1/models \
-H "Authorization: Bearer xero_myproject_your_api_key"
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']})")
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 https://api.xerotier.ai/proj_ABC123/v1/models/00000000-1111-0000-1111-000000000000?extended=true \
-H "Authorization: Bearer xero_myproject_your_api_key"
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']}")
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 -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
}'
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']}")
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
modelsscope - Project ownership of the model
curl -X DELETE https://api.xerotier.ai/proj_ABC123/v1/models/00000000-1111-0000-1111-000000000000 \
-H "Authorization: Bearer xero_myproject_your_api_key"
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()}")
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 -X POST https://api.xerotier.ai/proj_ABC123/v1/models/00000000-1111-0000-1111-000000000000/revalidate \
-H "Authorization: Bearer xero_myproject_your_api_key"
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']}")
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 https://api.xerotier.ai/proj_ABC123/v1/models/00000000-1111-0000-1111-000000000000/catalog-info \
-H "Authorization: Bearer xero_myproject_your_api_key"
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")
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"
}