Predict.aiDocs
Models

Custom models

Create your own architecture, browse your models and the public catalog, and fetch the workspace recommendation.

Create a model

POST /v1/models creates a model in your workspace. Every kind shares the same catalog fields plus a kind-specific body; this page shows the custom body (for the foundation body see Foundation models).

curl -X POST "$API_BASE/v1/models" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "kind": "custom",
    "name": "LSTM long range for markets",
    "purpose": "Improve the prediction of the next value in a timeseries dataset",
    "description": "Stacked LSTM layers for enhanced time series forecasting",
    "visibility": "private",
    "categories": ["stocks", "prediction"],
    "tags": ["stock market"],
    "metadata": {
      "framework": "TensorFlow",
      "framework_version": "2.x",
      "training_environment": "cloud"
    },
    "model_blueprint": {
      "model_type": "sequential",
      "layers": [
        { "type": "Input", "units": 3 },
        { "type": "LSTM", "units": 64, "activation": "tanh", "return_sequences": false },
        { "type": "Dropout", "rate": 0.2 },
        { "type": "Dense", "units": 1, "activation": "linear" }
      ]
    },
    "compilation_details": {
      "loss": "huber",
      "optimizer": { "type": "adamw", "learning_rate": 0.001, "weight_decay": 0.01 },
      "metrics": ["mae", "rmse"]
    },
    "training_details": { "epochs": 200, "batch_size": 64, "sequence_length": 20 },
    "data_split": { "test_split": 0.2, "validation_split": 0.2 },
    "data_preprocessing": { "global_scaler": "MinMaxScaler" }
  }'
{
  "data": {
    "uid": "c1c4d85a-42d9-476a-a6f1-fa8b22e29671",
    "message": "Model created successfully"
  }
}

Request body — catalog fields (every kind)

FieldMeaning
name requiredDisplay name for the catalog.
purpose requiredOne sentence on what the model is for.
description requiredLonger free-text description.
visibility requiredprivate (only you) or public (listed in the public catalog).
categories requiredArray of category strings for catalog filtering.
tags requiredArray of tag strings for catalog filtering.
metadata requiredCatalog metadata: framework, framework_version, training_environment.
kind optionalcustom (default) or foundation. BYOM models are created through their own flow.

Request body — custom architecture

FieldMeaning
model_blueprint requiredThe architecture. Neural frameworks: { "model_type": "sequential", "layers": […] }. scikit-learn: { "estimator": …, "hyperparameters": … }. XGBoost: { "hyperparameters": … }.
compilation_details requiredLoss, optimizer, and metrics for neural frameworks — { "loss", "optimizer": { "type", "learning_rate", … }, "metrics": […] }. Send {} for sklearn and XGBoost.
training_details optionalTraining knobs: epochs, batch_size, sequence_length (the lookback window per sample).
data_split optionaltest_split and validation_split fractions.
data_preprocessing optionale.g. { "global_scaler": "MinMaxScaler" }.

Supported frameworks: tensorflow (aliases keras, tf), pytorch, sklearn, and xgboost. TensorFlow and PyTorch use the layer schema above; scikit-learn takes model_blueprint.estimator + hyperparameters, XGBoost takes model_blueprint.hyperparameters — both with an empty compilation_details.

Before saving, the platform actually builds your model, runs a prediction, compiles it, and executes one training step on synthetic data. Anything that would crash a real run — incompatible layers, an unknown loss, a metric that doesn't fit the output shape — comes back as a 400 with a specific fix, not as a failed training an hour later. One fix is applied automatically: a recurrent layer with return_sequences: true followed directly by Dense is corrected for you.

Errors

StatusWhyExample message
400A required catalog field is missing"Missing required fields: purpose, categories"
400Bad visibility or kind value"Visibility must be either 'public' or 'private'"
400The kind-specific body failed validation"Invalid custom model: Neural-network models must contain a non-empty 'layers' array under model_blueprint."
403Plan quota reached"Model limit exceeded. Your plan allows 10 models per workspace."
500The model couldn't be saved"Failed to create model"

Once created, train the model by referencing its uid from a pipeline.

List your models

Returns the models you own in this workspace, newest first:

curl "$API_BASE/v1/models" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"
{
  "data": {
    "models": [
      {
        "uid": "c1c4d85a-42d9-476a-a6f1-fa8b22e29671",
        "kind": "custom",
        "name": "LSTM long range for markets",
        "visibility": "private",
        "categories": ["stocks", "prediction"],
        "tags": ["stock market"],
        "rating": 0,
        "in_use_by": 0,
        "created_at": "2026-07-15T08:30:00+00:00",

      }
    ]
  }
}

Get one model

curl "$API_BASE/v1/models/$MODEL_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"
{
  "data": {
    "model": {
      "uid": "c1c4d85a-42d9-476a-a6f1-fa8b22e29671",
      "kind": "custom",
      "name": "LSTM long range for markets",
      "owner_name": "Ada",
      "owner_username": "ada",

    }
  }
}

You can fetch any model you own and any public model; owner details are attached for catalog display. Foundation-model ids (pfm__…, extfm__…) work here too and return the synthesized catalog row.

StatusWhyExample message
403The model is private and isn't yours"Unauthorized access to model"
404No model with that id"Model not found"

Browse the public catalog

One paginated list across all kinds, plus foundation models:

curl "$API_BASE/v1/models/public?kind=all&page=1&limit=10&sort_by=rating&sort_order=desc" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"
{
  "data": {
    "models": [
      {
        "uid": "pfm__predictfm-f-v0.1",
        "kind": "foundation_backbone",
        "name": "PredictFM · predictfm-f-v0.1",
        "visibility": "public",
        "featured": 1,
        "foundation": { "task": "forecast", "license": "Apache-2.0",  },

      },
      {
        "uid": "8d1f0a3e-…",
        "kind": "custom",
        "name": "LSTM long range for markets",
        "owner_details": { "uid": "949e4f25-…", "username": "ada",  },

      }
    ],
    "pagination": {
      "total": 42,
      "page": 1,
      "page_count": 5,
      "has_next": true,
      "has_prev": false
    }
  }
}

Query parameters

ParameterMeaning
kind optionalall (default), custom, byom, foundation (fine-tune models plus foundation models), or foundation_backbone (foundation models only).
page optionalPage number, ≥ 1. Defaults to 1.
limit optionalRows per page, ≤ 100. Defaults to 10.
search optionalMatches the model name, case-insensitive.
framework / training_environment / owner optionalExact-match filters on catalog metadata.
categories / tags optionalRepeatable, e.g. categories=weather&categories=temperature.
sort_by optionalname, created_at, rating, or in_use_by. Default sort: featured, then rating, then usage.
sort_order optionalasc or desc.
include_deprecated optionalInclude deprecated foundation models. Defaults to false.
StatusWhyExample message
400page or limit isn't an integer"Invalid pagination parameters"

When signal analysis finds a model architecture that fits your workspace's data, it stores a single workspace-level recommendation. Any workspace member can fetch it:

curl "$API_BASE/v1/models/recommended" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Workspace-Id: $WORKSPACE_ID"
{
  "data": {
    "model": {
      "uid": "5b7e2c19-…",
      "kind": "custom",
      "name": "Recommended: GRU for daily_sales",
      "recommended": true,

    }
  }
}

Returns {"data": {"model": null}} when no recommendation exists yet.

On this page